以下的linq对我的大脑来说太过绝对,是我试图做的甚至可能吗?
var aa = new string[] { "1", "2" };
var bb = new string[] { "1", "2", "3" };
var cc = new string[] { "2" };
//*cannot directly reference the above anymore*//
var dd = new string[][] { aa, bb, cc };
//result = dd.**magical linq to only get item(s) present in each table** i.e. result = {"2"}
答案 0 :(得分:3)
可能有更简单的方法,但您可以在循环中构建查询:
var aa = new string[] { "1", "2" };
var bb = new string[] { "1", "2", "3" };
var cc = new string[] { "2" };
var dd=new string[][] { aa, bb, cc };
IEnumerable<string> q=dd.First();
for(var i=1;i<dd.Length;++i)
{
q=q.Intersect(dd[i]);
}
答案 1 :(得分:3)
var result = dd.Aggregate<IEnumerable<string>>((a, x) => a.Intersect(x));
如果你想要稍微好一点的理论性能,而牺牲一些可读性,那么你可以做以下事情。它避免了为每个交集操作构造新集合的需要,使用显式HashSet<T>
将结果传递给下一个迭代而不是普通IEnumerable<T>
。
var result = dd.Aggregate((HashSet<string>)null,
(a, x) => {
if (a == null)
a = new HashSet<string>(x);
else
a.IntersectWith(x);
return a;
});
答案 2 :(得分:3)
您可以使用集合运算符 - Union,Intersect等。
(编辑 - 误读问题!)
我相信Intersect会为您提供开箱即用的内容:
var dd = aa.Intersect(bb).Intersect(cc);
请注意,这将起作用,因为ab和cc已经是相同类型的所有IEnumebles。如果您的IEnumerables属于不同类型(例如来自不同的Linq表),您将需要投影所需的属性:
var dd = aa.Select(a => a.PropertyA).Intersect(bb.Select(b => b.PropertyB).Intersect(cc.Select(c => c.PropertyC);
结果会有一个IQueryable,所以你可以在末尾链接ToArray(),ToList()等,以得到你想要的结果。
答案 3 :(得分:3)
注意,如果您使用LINQ to SQL并将复合查询的任何部分强制转换为IEnumerable&lt;&gt;,则该部分不能与查询的其余部分组合以形成单个SQL查询。这将通过使用SQL作为示例中的数据源通过spender发生,其中查询被隐式地转换为IEnumerable&lt;&gt;当它被分配给'q'时。请改用IQueryable。尽管每个IEnumerable都是延迟的,但是三个SQL查询将被发送到服务器,并且交集将在内存中执行。
请参阅Returning IEnumerable<T> vs. IQueryable<T>或搜索“IEnumerable vs IQueryable”以获取参考资料。
答案 4 :(得分:0)
为什么不使用简单的连接?
class Program
{
static void Main(string[] args)
{
var aa = new string[] { "1", "2", "4" };
var bb = new string[] { "1", "2", "3", "4" };
var cc = new string[] { "2", "4" };
//*cannot directly reference the above anymore*//
var dd = new string[][] { aa, bb, cc };
var result = dd.Aggregate((x, y) => x.Join(y, z => z, z => z, (z, v) => z).ToArray());
foreach (var item in result)
{
Console.WriteLine(item);
}
Console.ReadLine();
}
}