I have such class:
public class Item
{
public int Id {get;set;}
public string A {get;set;}
public string B {get;set;}
public string C {get;set;}
}
And now I have an example dictionary which looks like this:
var dict = new Dictionary<<int, List<Item>>()
{
{
1,
new List<Item>()
{
new Item { Id = 1, A = "aaa", B = "bbb", C = "ccc" },
new Item { Id = 2, A = "q", B = "w", C = "e" }
}
},
{
2,
new List<Item>()
{
new Item { Id = 3, A = "aaa", B = "bbb", C = "ccc" },
new Item { Id = 4, A = "qqq", B = "www", C = "eee" }
}
},
{
3,
new List<Item>()
{
new Item { Id = 1, A = "aaa", B = "bbb", C = "ccc" },
new Item { Id = 5, A = "some", B = "other", C = "case" }
}
},
};
What I need to do is to find all Item
's which have equal values on properties A, B, C
for ALL keys, so as an output there should be an IEnumerable<Item> / List<Item>
.
For the example above, the output would contain a single Item
element with values:
A = "aaa", B = "bbb", C = "ccc"
because for each dictionary key an Item
object with those exact values exist.
Id
for this object could be taken from first Item
that matches, so it could be equal to 1
How would a LINQ query look for this?
答案 0 :(得分:2)
您要查找的查询看起来像这样:
dict
.SelectMany(d => d.Value)
.Where(d => dict.All(di => di.Value.Any(v => v.A == d.A && v.B == d.B && v.C == d.C)))
.GroupBy(d => new { A = d.A, B = d.B, C = d.C })
.Select(d => d.Key)
.ToList();
快速说明:
答案 1 :(得分:1)
另一种解决方案是使用Aggregate,并在Item类中覆盖GetHash,如下所示:
dict.SelectMany(x => x.Value)
.Aggregate(new Dictionary<Item, int>(), (map, item1) =>
{
if (map.ContainsKey(item1))
map[item1]++;
else map[item1] = 0;
return map;
})
.Where(y => y.Value > 0)
.Select(pair =>pair.Key);
项目覆盖:
public bool Equals(Item other)
{
return A == other?.A && B == other.B && C == other.C;
}
public override int GetHashCode()
{
int hash = 13;
hash = (hash * 7) + A.GetHashCode();
hash = (hash * 7) + B.GetHashCode();
hash = (hash * 7) + C.GetHashCode();
return hash;
}
答案 2 :(得分:1)
使用IEqualityComparer
,您可以轻松地:
选择所有“值”,“组”,“唯一过滤器”,“选择项目”。
var flatAllValues = dict.SelectMany(x => x.Value).ToList();
var group = flatAllValues
.GroupBy(p => p, new ItemComparer())
.Where(g => g.Count() > 1)
.Select(g => g.Key);
IEqualityComparer实现:
class ItemComparer : IEqualityComparer<Item>
{
public bool Equals(Item i1, Item i2)
{
if (i1 == null && i2 == null)
return true;
else if (i2 == null | i1 == null)
return false;
else if (i2.A == i1.A
&& i2.B == i1.B
&& i2.C == i1.C)
return true;
else
return false;
}
public int GetHashCode(Item i)
{
unchecked
{
int hash = 17;
hash = hash * 23 + i.A.GetHashCode();
hash = hash * 23 + i.B.GetHashCode();
hash = hash * 23 + i.C.GetHashCode();
return hash;
}
}
}