【问题标题】:How do I convert this nested foreach to linq C#如何将此嵌套的 foreach 转换为 linq C#
【发布时间】:2017-04-07 21:08:04
【问题描述】:

当我尝试将此嵌套的 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]);
    }
}

【问题讨论】:

  • 您尝试了哪些方法,具体而言,它以什么方式不起作用?
  • 你能把extractorResults、fileResults的实际类型放在一起吗?否则无法回答您的问题。

标签: c# performance linq lambda


【解决方案1】:

似乎您正在尝试“合并”两个字典:

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

解释:

  1. 从两个字典中获取所有 KeyValuePairs
  2. 按键对所有 KeyValuePair 进行分组
  3. 创建新字典,其中将包含每个组的条目 - 相同的键和从分组的 KeyValuePair 中选择的所有值的列表。如果您不希望结果重复,您可以在选择值后添加Distinct() 调用。尽管您最初的基于 foreach 的逻辑会产生重复项。

一步一步(我将使用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] }
 ]

【讨论】:

  • 工作 :),但是当我从 List 转换到 IList 时仍然遇到问题。感谢您的帮助。
【解决方案2】:

感谢大家的帮助,最后因为我无法从字典转换为 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);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-06-07
    • 1970-01-01
    • 1970-01-01
    • 2020-12-07
    • 1970-01-01
    • 1970-01-01
    • 2017-02-19
    • 1970-01-01
    相关资源
    最近更新 更多