【问题标题】:Expanding an IDictionary<Key, IEnumerable<Value>>扩展 IDictionary<Key, IEnumerable<Value>>
【发布时间】:2014-01-16 21:40:54
【问题描述】:

我目前有一个Dictionary&lt;Key, IEnumerable&lt;Value&gt;&gt;,我想扩展它,所以它会变成一个Dictionary&lt;Key, Value&gt;

用一个简单的 foreach 循环来做这件事很容易,但也很麻烦:

var result = new List<KeyValuePair<Key, Value>>();
foreach(var kvp in dict)
{
    foreach(var v in kvp.Value)
    {
        result.Add(new KeyValuePair<Key, Value>(kvp.Key, v));
    }
}

现在我想将其转换为单个 LINQ 查询,最好使用 lambda 语法。 (目前在项目中没有使用表达式语法anywhere,也不想从现在开始)

【问题讨论】:

  • 这应该会让你大吃一惊,因为字典只支持每个键的一个值。您需要一个 MultiDictionary,而基类库中没有内置这样的东西。
  • 首先,您还没有测试您尝试转换为单个 LINQ 查询的循环。这将在第一次遇到具有多个成员的 IEnumerable 值时引发“Key Already Exists”异常。
  • @Trillian @BolucPapuccuoglu 好点,我应该把它改成IEnumerable&lt;KeyValuePair&lt;Key, Value&gt;&gt;
  • @Kippie 或Lookup&lt;T&gt;

标签: c# linq lambda


【解决方案1】:

您不能两次添加相同的键,但这会在您的嵌套循环中发生。

如果您想将其展平为IEnumerable&lt;KeyValuePair&lt;Key, Value&gt;&gt;,您可以使用SelectMany

var dict = new Dictionary<string, IEnumerable<string>>();
IEnumerable<KeyValuePair<string, string>> flattenedDict = dict
    .SelectMany(kv => 
        kv.Value.Select(v => new KeyValuePair<string, string>(kv.Key, v)));

【讨论】:

  • 太棒了,干得好!
【解决方案2】:

如何使用 LINQ 内联:

var results = (from kvp in dict
                 from v in kvp.Value 
                 select new KeyValuePair<AddressType, ContractType>(kvp.Key, v))
                 .ToList();

不过,不知道 lambda 语法。

【讨论】:

  • 好吧,这行得通,不过我真的喜欢它是 lambda。
【解决方案3】:

您也许可以使用Lookup&lt;T&gt;,因为它支持每个值多个键,

var dict = new Dictionary<string, IEnumerable<string>>();
var lookUp = dictionary
    .SelectMany(pair => pair.Value
        .Select(value => new { Key = pair.Key, Value = value }))
    .ToLookup(pair => pair.Key, pair => pair.Value);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-17
    • 2013-09-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多