使用LINQ选择字典〈T1,T2>

dced5bon  于 2023-03-27  发布在  其他
关注(0)|答案(4)|浏览(164)

我使用了“select”关键字和扩展方法来返回一个IEnumerable<T>,但是我需要返回一个通用的Dictionary<T1, T2>,并且无法解决这个问题。我从中学到的示例使用了类似于以下形式的东西:

IEnumerable<T> coll = from x in y 
    select new SomeClass{ prop1 = value1, prop2 = value2 };

我也对扩展方法做了同样的事情。我假设因为Dictionary<T1, T2>中的项可以迭代为KeyValuePair<T1, T2>,所以我可以将上面示例中的“SomeClass”替换为“new KeyValuePair<T1, T2> { ...”,但这不起作用(Key和Value被标记为只读,所以我无法编译此代码)。
这是可能的吗?或者我需要分多个步骤来完成?
谢谢。

fcwjkofz

fcwjkofz1#

扩展方法还提供了一个ToDictionary扩展。它使用起来相当简单,一般的用法是传递一个lambda选择器作为键,并获取对象作为值,但你可以同时传递一个lambda选择器作为键和值。

class SomeObject
{
    public int ID { get; set; }
    public string Name { get; set; }
}

SomeObject[] objects = new SomeObject[]
{
    new SomeObject { ID = 1, Name = "Hello" },
    new SomeObject { ID = 2, Name = "World" }
};

Dictionary<int, string> objectDictionary = objects.ToDictionary(o => o.ID, o => o.Name);

那么objectDictionary[1]将包含值“Hello”

qacovj5a

qacovj5a2#

一个更明确的选择是将集合投影到KeyValuePair的IEnumerable,然后将其转换为Dictionary。

Dictionary<int, string> dictionary = objects
    .Select(x=> new KeyValuePair<int, string>(x.Id, x.Name))
    .ToDictionary(x=>x.Key, x=>x.Value);
wlp8pajw

wlp8pajw3#

var dictionary = (from x in y 
                  select new SomeClass
                  {
                      prop1 = value1,
                      prop2 = value2
                  }
                  ).ToDictionary(item => item.prop1);

这是假设SomeClass.prop1是字典所需的Key

2jcobegt

2jcobegt4#

我修改了hross的解决方案,因为他的版本将数组的所有元素放入一个字典元素中。
我希望每个数组项都在自己的字典项中。这有两个优点:

  • 如果你有包含对象的数组或其他数组而不是值,则更容易使用。
  • 字典键与Json.Net的JSON路径兼容。

这个解决方案的关键是JToken知道它的路径(JToken.Path),所以没有必要自己组装它。这使得新的解决方案出奇的简单。

public static Dictionary<string, string?>? GetJsonDictionary(JToken? token)
{
    if (token == null)
    {
        return null;
    }
    var dict = new Dictionary<string, string?>();
    ParseJToken(token, dict);
    return dict;
}

private static void ParseJToken(JToken token, Dictionary<string, string?> nodes)
{
    if (token.HasValues)
    {
        // The node has children.
        foreach (JToken child in token.Children())
        {
            ParseJToken(child, nodes);
        }
    }
    else
    {
        // The node is a leaf.
        nodes.Add(token.Path, token.ToString());
    }
}

相关问题