然后使用元组作为键过滤然后汇总字典

时间:2016-08-03 09:42:42

标签: c# dictionary filter tuples

我试图过滤,然后将一个字典与一个元组作为关键字。在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()

3 个答案:

答案 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.Item1tuple.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...
相关问题