如何将此嵌套foreach转换为linq C#

时间:2017-04-07 21:08:04

标签: c# performance linq lambda

当我尝试将这个嵌套的foreach转换为LINQ时,我无法做到。我尝试了几种方法但没有尝试。我没有得到这些foreach的结果

foreach (string field in extractorResults.Keys) {
    if (fileResults.ContainsKey(field)) {
        foreach (ExtractionResult exResult in extractorResults[field]) {
            fileResults[field].Add(exResult);
        }
    } else
        fileResults.Add(field, extractorResults[field]);
    }
}

2 个答案:

答案 0 :(得分:0)

好像你正试图“合并”两个词典:

fileResults = fileResults.Concat(extractorResults)
                 .GroupBy(kvp => kvp.Key)
                 .ToDictionary(g => g.Key, g => g.SelectMany(kvp => kvp.Value).ToList());

说明:

  1. 从两个词典中获取所有KeyValuePairs
  2. 按键分组所有KeyValuePairs
  3. 创建新词典,其中包含每个组的条目 - 相同的键和从分组的KeyValuePairs中选择的所有值的列表。如果您不希望在结果中重复,则可以在选择值后添加Distinct()调用。虽然你原来的基于foreach的逻辑会产生重复。
  4. 一步一步(我将使用JSON格式显示数据流):

    假设您有两个带有以下数据的词典(实际数据类型无关紧要):

      fileResults = [
         { key:"a", value: [1,2] },
         { key: "b", value: [5] }
      ];
    
      extractorResults = [
         { key:"c", value: [7] },  
         { key: "b", value: [3,4] }
      ];
    

    连接这些词典后,您将获得一系列键值对

     [
        { key:"a", value: [1,2] }, 
        { key: "b", value: [5] },
        { key:"c", value: [7] },  
        { key: "b", value: [3,4] }
     ]
    

    接下来分组:

     [
        { key: "a", items: [ { key:"a", value: [1,2] } ] },
        { key: "b", items: [ { key: "b", value: [5] }, { key: "b", value: [3,4] },
        { key: "c", items: [ { key:"c", value: [7] } ]
     ]
    

    最后,我们创建了一个包含上述每个组条目的新词典:

     [
        { key: "a", value: [1, 2] },
        { key: "b", value: [5, 3, 4] },
        { key: "c", value: [7] }
     ]
    

答案 1 :(得分:0)

感谢大家的帮助,最后因为我无法从字典转换为IDictionary这对我有用:

var mergeResults = fileResults.Concat(extractorResults)
                    .GroupBy(kvp => kvp.Key)
                    .ToDictionary(g => g.Key, g => g.SelectMany(kvp => kvp.Value).ToList())
                    .Where(kvp => !fileResults.ContainsKey(kvp.Key));

                var kvpMergeResults = mergeResults as IList<KeyValuePair<string, List<Result>>> ?? mergeResults.ToList();
                fileResults.Add(kvpMergeResults.First().Key, kvpMergeResults.First().Value);