I'm looking for an efficient way of sorting an array of email addresses to avoid items with the same domain to be consecutive, in C#.
Email addresses inside the array are already distinct and all of them are lower case.
Example:
Given an array with the following entries:
[email protected]
[email protected]
[email protected]
[email protected]
I would like to obtain something similar to the following:
[email protected]
[email protected]
[email protected]
[email protected]
With the help of an extension method (stolen from https://stackoverflow.com/a/27533369/172769), you can go like this:
List<string> emails = new List<string>();
emails.Add("[email protected]");
emails.Add("[email protected]");
emails.Add("[email protected]");
emails.Add("[email protected]");
var q = emails.GroupBy(m => m.Split('@')[1]).Select(g => new List<string>(g)).Interleave();
The Interleave
method is defined as:
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();
}
}
}
So basically, we create groups based on the domain part of the email adresses, project (or Select) each group into a List<string>
, and then "Interleave" those lists.
I have tested against your sample data, but more thorough testing might be needed to find edge cases.
Cheers