假设我有一个包含人名和他们的起源城市的对象.
public class personDetails
{
public string City;
public string Name;
}
Run Code Online (Sandbox Code Playgroud)
我有一个列表,添加了以下条目.
Name City
John | London
Jane | London
Tom | New York
Bob | New York
Fred | New York
Run Code Online (Sandbox Code Playgroud)
我正在寻找的是所有可能的名称组合,按城市分组.
John Tom
John Bob
John Fred
Jane Tom
Jane Bob
Jane Fred
Run Code Online (Sandbox Code Playgroud)
如果通过使用以下代码事先知道组的数量,我可以这样做
List<personDetails> personList = new List<personDetails>();
//populate list
var groupedPersons = personList.GroupBy(c => c.City);
foreach (var item1 in groupedPersons[0])
{
foreach (var item2 in groupedPersons[1])
{
Console.WriteLine(item1.Name + " " + item2.Name);
}
}
Run Code Online (Sandbox Code Playgroud)
但是,这只有在我事先知道群组数量的情况下才有效,并随着群组数量的增加而变得笨拙.我确信有一种优雅的方法可以使用LINQ来实现这一点,任何人都可以解决这个问题吗?
我们将从这里逐字获取的以下代码片段开始。(这是一个很好的链接,值得一读)。
public static class MyExtensions
{
public static IEnumerable<IEnumerable<T>> CartesianProduct<T>(this IEnumerable<IEnumerable<T>> sequences)
{
IEnumerable<IEnumerable<T>> emptyProduct = new[] { Enumerable.Empty<T>() };
return sequences.Aggregate(
emptyProduct,
(accumulator, sequence) =>
from accseq in accumulator
from item in sequence
select accseq.Concat(new[] { item }));
}
}
Run Code Online (Sandbox Code Playgroud)
之后我们需要做的就是:
var groupedPersons = personList.GroupBy(c => c.City)
//need an enumerable of enumerables, not an enumerable of groupings,
//because the method isn't covariant.
.Select(group => group.AsEnumerable());
var results = groupedPersons.CartesianProduct();
foreach (var group in results)
{
foreach (var person in group)
{
Console.Write(person.Name + " ");
}
System.Console.WriteLine();
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
617 次 |
最近记录: |