我试图过滤,然后将一个字典与一个元组作为关键字。在SO上有几个links,但没有什么广泛的。有什么建议吗?
Dictionary<Tuple<int, string, string, int, string>, double> dctMC = new Dictionary<Tuple<int, string, string, int, string>, double>();
List<int> listIDs = new List<int> { 1, 3, 5 };
// ID, TYPE, NAME, ORDER, COLOUR, WEIGHT
dctMC.Add(Tuple.Create(1, "Fruit", "Apple", 9, "Green"), 0.45);
dctMC.Add(Tuple.Create(2, "Fruit", "Grape", 5, "Red"), 0.78);
dctMC.Add(Tuple.Create(3, "Fruit", "Apple", 9, "Green"), 0.33);
dctMC.Add(Tuple.Create(4, "Fruit", "Peach", 2, "Yellow"), 0.89);
dctMC.Add(Tuple.Create(5, "Fruit", "Apple", 14, "Red"), 0.23);
// Sum dictionary where IDs in listIDs, Type = FRUIT, Name = APPLE, Order = 9, Colour = "Green"
double TOTAL = dctMC.Where(Z => listIDs.Contains(Z.Key(item1)) &&
Z.Key(item2) == "Apple" &&
Z.Key(item3) == 9 &&
Z.Key(item4) == "Green")
.Sum()
答案 0 :(得分:4)
您的错误在于您访问元组键中的项目。他们是他的财产。
因此,如果您尝试将其置于单词中,那就是:"Item in dictionary(KeyValuePair<>).Key.(Key is a tuple with 5 fields - so select property of that field)"
最后 - 在找到符合您要求的项目后,您会收到IEnumerable<KeyValuePair<>>
,所以当您Sum
时,您应该通过什么指定 - 在这种情况下,Value
对
double TOTAL = dctMC.Where(Z => listIDs.Contains(Z.Key.Item1) &&
Z.Key.Item2 == "Apple" &&
Z.Key.Item4 == 9 &&
Z.Key.Item5 == "Green")
.Sum(item => item.Value);
**另请注意,您意外使用Item3 == 9
代替Item4
,而Item4 == "Green"
代替Item5
*
不知道这是否是出于问题的原因,但我建议远离这样的Tuples
并将其放入适当的定义类(或匿名类型)如果它来自其他一些查询)
答案 1 :(得分:2)
当您遍历字典时,元素为KeyValuePair<>
个实例。您需要Select
值来总结它们:
double TOTAL = dctMC.Where(Z =>
lstIDs.Contains(Z.Key.Item1)) &&
Z.Key.Item2 == "Apple" &&
Z.Key.Item4 == 9 && Z.Key.Item5 == "Green")
.Select(Z => Z.Value)
.Sum();
或使用Sum()
重载与选择器lambda,如下所示:
double TOTAL = dctMC.Where(Z =>
lstIDs.Contains(Z.Key.Item1)) &&
Z.Key.Item2 == "Apple" &&
Z.Key.Item4 == 9 && Z.Key.Item5 == "Green")
.Sum(Z => Z.Value);
请注意Tuple<>
中的项目的访问权限类似于tuple.Item1
,tuple.Item2
等,而不是tuple(item1)
。
答案 2 :(得分:2)
如果你把它分成几个阶段,你就更容易绕过它:
首先过滤掉不相关的项目(按键),然后对值进行求和:
var filtered = //This is an IEnumerable of KeyValuePair<Tuple<int, string, string, int, string>, double>
dctMC.Where(Z => listIDs.Contains(Z.Key.Item1) &&
Z.Key.Item2 == "Apple" &&
Z.Key.Item4 == 9 &&
Z.Key.Item5 == "Green")
var values = filtered.Select(item => item.Value); //the doubles you want to sum
double TOTAL = values.Sum(); //The sum you were looking for...