我需要 LINQ 查询来获取以下结构的所有组合(按名称区分):
var keys = new[]
{
new { Name = "A", Value = "1" },
new { Name = "A", Value = "2" },
new { Name = "B", Value = "3" },
new { Name = "B", Value = "4" },
// etc
};
我需要得到:
{A1, B3} {A1, B4} {A2, B3} {A2, B4} // etc
其中 A1-B4 是指整个项目:{ Name = "...", Value = "..." }
源数组不仅可以包含 A 和 B 元素。例如,如果我们添加项目{ Name = "C", Value = "5" }
输出结果项目应包含 3 个元素,例如 {A1, B3, C5}
.
谢谢。
此问题有多个步骤:
- 按"名称"将列表分隔为列表列表 L
- 执行列表 LxL 的笛卡尔乘积,其中列表是不同的
- Perfrom 每对列表的笛卡尔乘积
- 合并所有结果。
下面是一个实现:
var NameLists = keys.GroupBy(k => k.Name);
var NameListPairs = from first in NameLists
from second in NameLists where first != second
select new {first, second};
var Result = from pair in NameListPairs
from first in pair.first
from second in pair.second
select new {first, second};
你有它。 注意如何做笛卡尔积的一般模式,我们一次选择两个枚举。
编辑:
如果你想做的是所有名称列表中的笛卡尔产品,那么使用Eric Lippert的这个片段。 有了这个,你可以像这样使用它:
var Result = keys.GroupBy(k => k.Name).CartesianProduct();
尝试这样的事情:
var combinations = from A in keys.Where(k=>k.Name == "A")
from B in keys.Where(k=>k.Name == "B")
select new {A,B};
如果你想使用 Linq,那么看看 Join 运算符,并在其中破解你自己的比较器。
在此比较器中,您可以匹配键和值都不同的项目。
//
// Summary:
// Correlates the elements of two sequences based on matching keys. A specified
// System.Collections.Generic.IEqualityComparer<T> is used to compare keys.
//
// Parameters:
// outer:
// The first sequence to join.
//
// inner:
// The sequence to join to the first sequence.
//
// outerKeySelector:
// A function to extract the join key from each element of the first sequence.
//
// innerKeySelector:
// A function to extract the join key from each element of the second sequence.
//
// resultSelector:
// A function to create a result element from two matching elements.
//
// comparer:
// An System.Collections.Generic.IEqualityComparer<T> to hash and compare keys.
//
// Type parameters:
// TOuter:
// The type of the elements of the first sequence.
//
// TInner:
// The type of the elements of the second sequence.
//
// TKey:
// The type of the keys returned by the key selector functions.
//
// TResult:
// The type of the result elements.
//
// Returns:
// An System.Collections.Generic.IEnumerable<T> that has elements of type TResult
// that are obtained by performing an inner join on two sequences.
//
// Exceptions:
// System.ArgumentNullException:
// outer or inner or outerKeySelector or innerKeySelector or resultSelector
// is null.
public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult>(this IEnumerable<TOuter> outer, IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector, Func<TInner, TKey> innerKeySelector, Func<TOuter, TInner, TResult> resultSelector, IEqualityComparer<TKey> comparer);
这将获得所有组合,包括 {B3、A1} 等。
var cobinations = from a in keys
from b in keys.Where(k => k.Name != a.Name)
select new{ a, b };