我有一个具有List属性的类,我将这个类命名为A.然后我有一个List<A>
。
我需要LINQ for objects来获取List<A>
上所有项目中存在的所有对象B.
澄清的例子:
var list = new List<A>
{
new A { B = new List<B> { B1, B2, B3, B4 } }
new A { B = new List<B> { B3, B4, B5, B6 } }
new A { B = new List<B> { B2, B3, B4, B5, B6 } }
};
查询必须返回对象B3和B4,因为它们是所有List<A>
个对象中唯一包含的对象。
答案 0 :(得分:10)
如果您有一个列表列表,并且您想要所有内部列表中的元素,则可以使用Aggregate
和Intersect
的组合,如下所示:
IEnumerable<IEnumerable<string>> listOfLists = new string[][] {
new string[] { "B1", "B2", "B3", "B4" },
new string[] { "B3", "B4", "B5", "B6" },
new string[] { "B2", "B3", "B4", "B5", "B6" }
};
IEnumerable<string> commonElements = listOfLists.Aggregate(Enumerable.Intersect);
答案 1 :(得分:4)
您可以使用Intersect()
,前提是至少有一个元素,而您的班级B
有足够的平等实施/ GetHashCode()
:
IEnumerable<B> allBs = list[0].B;
foreach (var item in list.Skip(1))
{
allBs = allBs.Intersect(item.B);
}
除了增加复杂性之外,我认为Linq解决方案没有任何好处。
答案 2 :(得分:2)
只要为类型B的对象正确定义了Equals / GetHashCode,那么这实际上有点简单:
_listToQuery.Aggregate(
_listToQuery.First().B,
(seed, nextItem) => { seed = seed.Intersect(nextItem.B); return seed; })
或者,另一种方式:
_listToQuery.SelectMany(tr => tr.B)
.GroupBy(tr => tr)
.Where(tr => tr.Count() == _listToQuery.Count)
.Select(tr => tr.Key)
答案 3 :(得分:2)
我接近这个的方法是创建一个所有B的列表,然后通过一些唯一标识符(或者只有对象,如果它们是可比较的)对它们进行分组,找出哪些B出现不止一次。对它们进行分组后,选择实例数大于1的那些,使用每个分组的第一个实例作为规范代表。
var selection = list.SelectMany( a => a.B )
.GroupBy( b => b.UniqueID, b => b )
.Where( b => b.Count() > 1 )
.Select( b => b.First() );