C# 交错电子邮件地址数组,避免具有相同域的项目连续
我正在寻找一种有效的方法对电子邮件地址数组进行排序,以避免具有相同域的项目在C#中连续出现 阵列中的电子邮件地址已经不同,并且都是小写的 例如: 给定包含以下项的数组:C# 交错电子邮件地址数组,避免具有相同域的项目连续,c#,arrays,algorithm,sorting,email-address,C#,Arrays,Algorithm,Sorting,Email Address,我正在寻找一种有效的方法对电子邮件地址数组进行排序,以避免具有相同域的项目在C#中连续出现 阵列中的电子邮件地址已经不同,并且都是小写的 例如: 给定包含以下项的数组: john.doe@domain1.com jane_doe@domain1.com patricksmith@domain2.com erick.brown@domain3.com 我想获得与以下类似的信息: john.doe@domain1.com patricksmith@domain2.com jane_doe@
john.doe@domain1.com
jane_doe@domain1.com
patricksmith@domain2.com
erick.brown@domain3.com
我想获得与以下类似的信息:
john.doe@domain1.com
patricksmith@domain2.com
jane_doe@domain1.com
erick.brown@domain3.com
我在这里要做的是首先对它们进行排序。 然后我从另一端重新安排。我相信有更有效的方法可以做到这一点,但这是一个简单的方法
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication4
{
class Program
{
static void Main(string[] args)
{
String[] emails = { "john.doe@domain1.com", "jane_doe@domain1.com", "patricksmith@domain2.com", "erick.brown@domain3.com" };
var result = process(emails);
}
static String[] process(String[] emails)
{
String[] result = new String[emails.Length];
var comparer = new DomainComparer();
Array.Sort(emails, comparer);
for (int i = 0, j = emails.Length - 1, k = 0; i < j; i++, j--, k += 2)
{
if (i == j)
result[k] = emails[i];
else
{
result[k] = emails[i];
result[k + 1] = emails[j];
}
}
return result;
}
}
public class DomainComparer : IComparer<string>
{
public int Compare(string left, string right)
{
int at_pos = left.IndexOf('@');
var left_domain = left.Substring(at_pos, left.Length - at_pos);
at_pos = right.IndexOf('@');
var right_domain = right.Substring(at_pos, right.Length - at_pos);
return String.Compare(left_domain, right_domain);
}
}
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
命名空间控制台应用程序4
{
班级计划
{
静态void Main(字符串[]参数)
{
字符串[]电子邮件={“john”。doe@domain1.com简_doe@domain1.com", "patricksmith@domain2.com埃里克。brown@domain3.com" };
var结果=过程(电子邮件);
}
静态字符串[]进程(字符串[]电子邮件)
{
字符串[]结果=新字符串[emails.Length];
var comparer=new DomainComparer();
排序(电子邮件、比较器);
对于(inti=0,j=email.Length-1,k=0;i
类似的内容会将它们平均分布,但在新列表的末尾会出现问题(=连续元素)
var list = new List<string>();
list.Add("john.doe@domain1.com");
list.Add("jane_doe@domain1.com");
list.Add("patricksmith@domain2.com");
list.Add("erick.brown@domain3.com");
var x = list.GroupBy(content => content.Split('@')[1]);
var newlist = new List<string>();
bool addedSomething=true;
int i = 0;
while (addedSomething) {
addedSomething = false;
foreach (var grp in x) {
if (grp.Count() > i) {
newlist.Add(grp.ElementAt(i));
addedSomething = true;
}
}
i++;
}
var list=newlist();
列表。添加(“john。doe@domain1.com");
列表。添加(“jane_doe@domain1.com");
列表。添加(“patricksmith@domain2.com");
列表。添加(“erick。brown@domain3.com");
var x=list.GroupBy(content=>content.Split('@')[1]);
var newlist=新列表();
bool addedSomething=真;
int i=0;
while(添加了一些内容){
addedSomething=false;
foreach(x中的var grp){
如果(grp.Count()>i){
新增(grp.ElementAt(i));
addedSomething=true;
}
}
i++;
}
这将使它们半均匀地分布,并试图避免彼此相邻的匹配域(尽管在某些列表中这可能是不可能的)。这个答案将使用OOP和Linq
使用系统;
使用System.Linq;
使用System.Collections.Generic;
公共课程
{
公共静态void Main()
{
var seed=新列表()
{
"1@a.com",
"2@a.com",
"3@a.com",
"4@a.com",
"5@a.com",
"6@a.com",
"7@a.com",
"8@a.com",
"9@a.com",
"10@a.com",
"1@b.com",
"2@b.com",
"3@b.com",
"1@c.com",
"4@b.com",
"2@c.com",
"3@c.com",
"4@c.com"
};
变量工作=种子
//创建EmailAddress对象的列表
.Select(s=>newemailaddress))//s.ToLowerCase()?
//按域对列表进行分组
.GroupBy(s=>s.Domain)
//创建一个列表
.选择(g=>new EmailAddressGroup(g))
.ToList();
var currentDomain=string.Empty;
而(work.Count>0)
{
//此列表不应与我们刚才使用的域相同
var noDups=work.Where(w=>w.Domain!=currentDomain);
//如果不存在,我们就完成了,否则就无法解决
if(noDups.Count()==0)
{
打破
}
//查找项目最多的第一组
var workGroup=noDups.First(w=>w.Count()==noDups.Max(g=>g.Count());
//获取电子邮件地址并将其从组列表中删除
var workItem=workGroup.Remove();
//如果组为空,请将其从*工作中删除*
if(workGroup.Count()==0)
{
工作。移除(工作组);
Console.WriteLine(“删除:“+workGroup.Domain”);
}
Console.WriteLine(workItem.FullEmail);
//上次查看的域。
currentDomain=工作项域;
}
Console.WriteLine(“无法有效分散电子邮件地址,剩余:”);
foreach(工作中的var工作组)
{
while(workGroup.Count()>0)
{
var item=workGroup.Remove();
Console.WriteLine(item.FullEmail);
}
}
}
公共类电子邮件地址
{
公共电子邮件地址(字符串电子邮件地址)
{
//附加电子邮件地址验证
var result=emailAddress.Split(新字符[]{'@},StringSplitOptions.RemoveEmptyEntries)
.ToList();
如果(result.Count()!=2)
{
新的例外情况(“电子邮件地址”);
}
this.FullEmail=电子邮件地址;
this.Name=结果[0];
this.Domain=结果[1];
}
using System;
using System.Linq;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
var seed = new List<string>()
{
"1@a.com",
"2@a.com",
"3@a.com",
"4@a.com",
"5@a.com",
"6@a.com",
"7@a.com",
"8@a.com",
"9@a.com",
"10@a.com",
"1@b.com",
"2@b.com",
"3@b.com",
"1@c.com",
"4@b.com",
"2@c.com",
"3@c.com",
"4@c.com"
};
var work = seed
// Create a list of EmailAddress objects
.Select(s => new EmailAddress(s)) // s.ToLowerCase() ?
// Group the list by Domain
.GroupBy(s => s.Domain)
// Create a List<EmailAddressGroup>
.Select(g => new EmailAddressGroup(g))
.ToList();
var currentDomain = string.Empty;
while(work.Count > 0)
{
// this list should not be the same domain we just used
var noDups = work.Where(w => w.Domain != currentDomain);
// if none exist we are done, or it can't be solved
if (noDups.Count() == 0)
{
break;
}
// find the first group with the most items
var workGroup = noDups.First(w => w.Count() == noDups.Max(g => g.Count()));
// get the email address and remove it from the group list
var workItem = workGroup.Remove();
// if the group is empty remove it from *work*
if (workGroup.Count() == 0)
{
work.Remove(workGroup);
Console.WriteLine("removed: " + workGroup.Domain);
}
Console.WriteLine(workItem.FullEmail);
// last domain looked at.
currentDomain = workItem.Domain;
}
Console.WriteLine("Cannot disperse email addresses affectively, left overs:");
foreach(var workGroup in work)
{
while(workGroup.Count() > 0)
{
var item = workGroup.Remove();
Console.WriteLine(item.FullEmail);
}
}
}
public class EmailAddress
{
public EmailAddress(string emailAddress)
{
// Additional Email Address Validation
var result = emailAddress.Split(new char[] {'@'}, StringSplitOptions.RemoveEmptyEntries)
.ToList();
if (result.Count() != 2)
{
new ArgumentException("emailAddress");
}
this.FullEmail = emailAddress;
this.Name = result[0];
this.Domain = result[1];
}
public string Name { get; private set; }
public string Domain { get; private set; }
public string FullEmail { get; private set; }
}
public class EmailAddressGroup
{
private List<EmailAddress> _emails;
public EmailAddressGroup(IEnumerable<EmailAddress> emails)
{
this._emails = emails.ToList();
this.Domain = emails.First().Domain;
}
public int Count()
{
return _emails.Count();
}
public string Domain { get; private set; }
public EmailAddress Remove()
{
var result = _emails.First();
_emails.Remove(result);
return result;
}
}
}
private IEnumerable<string> GetNonConsecutiveEmails(List<string> list)
{
var emailAddresses = list.Distinct().Select(email => new EmailAddress { Email = email, Domain = email.Split('@')[1]}).ToArray();
var groups = emailAddresses
.GroupBy(addr => addr.Domain)
.Select (group => new { Domain = group.Key, EmailAddresses = new Stack<EmailAddress>(group)})
.ToList();
EmailAddress lastEmail = null;
while(groups.Any(g => g.EmailAddresses.Any()))
{
// Try and pick from the largest stack.
var stack = groups
.Where(g => (g.EmailAddresses.Any()) && (lastEmail == null ? true : lastEmail.Domain != g.Domain))
.MaxBy(g => g.EmailAddresses.Count);
// Null check to account for only 1 stack being left.
// If so, pop the elements off the remaining stack.
lastEmail = (stack ?? groups.First(g => g.EmailAddresses.Any())).EmailAddresses.Pop();
yield return lastEmail.Email;
}
}
class EmailAddress
{
public string Domain;
public string Email;
}
public static class Extensions
{
public static T MaxBy<T,U>(this IEnumerable<T> data, Func<T,U> f) where U:IComparable
{
return data.Aggregate((i1, i2) => f(i1).CompareTo(f(i2))>0 ? i1 : i2);
}
}
List<string> emails = new List<string>();
emails.Add("john.doe@domain1.com");
emails.Add("jane_doe@domain1.com");
emails.Add("patricksmith@domain2.com");
emails.Add("erick.brown@domain3.com");
var q = emails.GroupBy(m => m.Split('@')[1]).Select(g => new List<string>(g)).Interleave();
public static IEnumerable<T> Interleave<T>(this IEnumerable<IEnumerable<T>> source )
{
var queues = source.Select(x => new Queue<T>(x)).ToList();
while (queues.Any(x => x.Any())) {
foreach (var queue in queues.Where(x => x.Any())) {
yield return queue.Dequeue();
}
}
}