我正在尝试获取dataB中dataA中的项子集,并且具有不同的属性c值。属性a和b可以用作索引,因此我尝试仅筛选出有用的对,然后检查它们是否具有不同的c值。
这是我提出的linq表达式,它确实有效,但似乎必须有更好/更快的方法来找到这个子集。
var itemsInBoth = from item in dataA
from item2 in dataB
where item.a == item2.a && item.b == item2.b
select new
{
first= item,
second = item2
};
var haveDifferentC = from item in itemsInBoth
where item.first.c != item.second.c
select item.first;
答案 0 :(得分:3)
根据David B提供的答案,我最终确定了他方法的略微修改版本。虽然差异很小,但我认为我会分享这个,主要是为那些喜欢表达语法的人(比如我)展示一个版本。
另外,我决定使用匿名键/值对来简化结构,而不是分组。
var dictA = (from item in dataA
select new
{
key = CreateIndexValue(item.a, item.b),
value = item
}).ToDictionary(kv => kv.key, kv => kv.value);
var dictB = (from item in dataB
select new
{
key = CreateIndexValue(item.a, item.b),
value = item
}).ToDictionary(kv => kv.key, kv => kv.value);
var filesInBoth = from item in dictA
where dictB.ContainsKey(item.Key)
select new
{
itemA = dictA[item.Key],
itemB = dictB[item.Key]
};
var differentSize = from item in filesInBoth
where item.itemA.c!= item.itemB.c
select item.itemA;
答案 1 :(得分:2)
更快?你有的是O(n ^ 2)。第一个列表中的每个项目将完全迭代第二个列表中的项目。您需要删除该连接中的冗余迭代。一种方法是使用另一种结构对匹配进行O(1)查找。
这是一些未经测试的(未经检查的)代码:
var dictionaryA = dataA
.GroupBy(item => new {a = item.a, b = item.b})
.ToDictionary(g => g.Key, g => g.ToList());
var dictionaryB = dataB
.GroupBy(item => new {a = item.a, b = item.b})
.ToDictionary(g => g.Key, g => g.ToList());
var results = dictionaryA
.Where(g1 => dictionaryB.ContainsKey(g1.Key))
.Select(g1 => new {g1 = g1, g2 = dictionaryB[g1.Key]})
.SelectMany(pair =>
pair.g1.SelectMany(item1 =>
pair.g2
.Where(item2 => item2.c != item1.c)
.Select(item2 => new {item1, item2})
)
);
如果a,b对在每个列表中都是唯一的,那么这是一个简化版本。
var dictionaryA = dataA
.ToDictionary(item => new {a = item.a, b = item.b}, item => item);
var dictionaryB = dataB
.ToDictionary(item => new {a = item.a, b = item.b}, item => item);
var results = dictionaryA
.Where(e1 => dictionaryB.ContainsKey(e1.Key))
.Select(e1 => new {i1 = e1.Value, i2 = dictionaryB[e1.Key]})
.Where(pair => pair.i1.c != pair.i2.c);