如何比较两个属性组合的两个列表和 select 在第三个 属性 中不匹配的行?
How to compare two lists on a combination of two properties and select a row which has mismatch in the third property?
我想根据两个属性(国家/地区和城市)的组合比较以下两个列表。
比较时,印度-钦奈出现在两个列表中并且具有相同的值 (1)。同样,UK-London 也出现在两个列表中并且具有相同的值 (3)。但是,尽管美国-纽约同时出现在两个列表中,但它们的值并不匹配(列表 1 中有 2 个,列表 2 中有 5 个)。
请帮我将最短的 linq 表达式写到 select list1 中的 '2-USA-New York',因为它的值与 list2 ('5-USA-New York') 不匹配。
void Main()
{
List<A> list1 = new List<A> {
new A { Country = "India", City = "Chennai", Value = 1 },
new A { Country = "USA", City = "New York", Value = 2 },
new A { Country = "UK", City = "London", Value = 3 }
};
List<A> list2 = new List<A> {
new A { Country = "India", City = "Chennai", Value = 1 },
new A { Country = "USA", City = "New York", Value = 5 },
new A { Country = "UK", City = "London", Value = 3 }
};
list1.Dump();
list2.Dump();
}
class A
{
public int Value { get; set; }
public string Country { get; set; }
public string City { get; set; }
}
假设您的列表中没有重复的 { Country, City }
对:
var list1Missmatched = list1
.Join(list2,
left => new { left.Country, left.City },
right => new { right.Country, right.City },
(left, right) => new { left, right })
.Where(x => x.left.Value != x.right.Value)
.Select(x => x.left)
.ToList();
这是可行的,因为在 leftList.Join(rightList, leftMatchBy, rightMatchBy, matchedPairResultSelector)
中我们使用 'anonymous object' 作为要匹配的键。匿名对象的相等性(和哈希码)的行为与值类型相同,即 new { Foo = 1 }
和 new { Foo = 1 }
相等并且具有相同的哈希码,即使它们是两个不同的实例。
Join
从 (matchByKey, listItem) 对中构建散列 table,这允许几乎线性的算法复杂度 - O(n)(与 Where(Any())
解决方案对比,具有二次复杂度 - O(n^2))。
如果你有兴趣,最近我写了一篇比较这两种方法的小文章performance test。
我知道这个问题已经得到了令人满意的回答,但这里有一个替代解决方案。
对于某些人来说,这可能更直观/更容易理解,因为它避免了整个 join-概念,而只是寻找 任何匹配的行当前行 代替。
但是,您可以预期类似此解决方案的解决方案比上述解决方案慢,尤其是对于更长/更复杂的列表,因此请记住这一点,并且仅将其用于更简单的情况。
var result = list1
.Where(rowFromFirst =>
list2.Any(rowFromSecond =>
rowFromSecond.Country == rowFromFirst.Country &&
rowFromSecond.City == rowFromFirst.City &&
rowFromSecond.Value != rowFromFirst.Value));
我想根据两个属性(国家/地区和城市)的组合比较以下两个列表。
比较时,印度-钦奈出现在两个列表中并且具有相同的值 (1)。同样,UK-London 也出现在两个列表中并且具有相同的值 (3)。但是,尽管美国-纽约同时出现在两个列表中,但它们的值并不匹配(列表 1 中有 2 个,列表 2 中有 5 个)。
请帮我将最短的 linq 表达式写到 select list1 中的 '2-USA-New York',因为它的值与 list2 ('5-USA-New York') 不匹配。
void Main()
{
List<A> list1 = new List<A> {
new A { Country = "India", City = "Chennai", Value = 1 },
new A { Country = "USA", City = "New York", Value = 2 },
new A { Country = "UK", City = "London", Value = 3 }
};
List<A> list2 = new List<A> {
new A { Country = "India", City = "Chennai", Value = 1 },
new A { Country = "USA", City = "New York", Value = 5 },
new A { Country = "UK", City = "London", Value = 3 }
};
list1.Dump();
list2.Dump();
}
class A
{
public int Value { get; set; }
public string Country { get; set; }
public string City { get; set; }
}
假设您的列表中没有重复的 { Country, City }
对:
var list1Missmatched = list1
.Join(list2,
left => new { left.Country, left.City },
right => new { right.Country, right.City },
(left, right) => new { left, right })
.Where(x => x.left.Value != x.right.Value)
.Select(x => x.left)
.ToList();
这是可行的,因为在 leftList.Join(rightList, leftMatchBy, rightMatchBy, matchedPairResultSelector)
中我们使用 'anonymous object' 作为要匹配的键。匿名对象的相等性(和哈希码)的行为与值类型相同,即 new { Foo = 1 }
和 new { Foo = 1 }
相等并且具有相同的哈希码,即使它们是两个不同的实例。
Join
从 (matchByKey, listItem) 对中构建散列 table,这允许几乎线性的算法复杂度 - O(n)(与 Where(Any())
解决方案对比,具有二次复杂度 - O(n^2))。
如果你有兴趣,最近我写了一篇比较这两种方法的小文章performance test。
我知道这个问题已经得到了令人满意的回答,但这里有一个替代解决方案。
对于某些人来说,这可能更直观/更容易理解,因为它避免了整个 join-概念,而只是寻找 任何匹配的行当前行 代替。
但是,您可以预期类似此解决方案的解决方案比上述解决方案慢,尤其是对于更长/更复杂的列表,因此请记住这一点,并且仅将其用于更简单的情况。
var result = list1
.Where(rowFromFirst =>
list2.Any(rowFromSecond =>
rowFromSecond.Country == rowFromFirst.Country &&
rowFromSecond.City == rowFromFirst.City &&
rowFromSecond.Value != rowFromFirst.Value));