【问题标题】:C# get keys and values from List<KeyValuePair<string, string>C# 从 List<KeyValuePair<string, string> 获取键和值
【发布时间】:2015-07-14 18:24:36
【问题描述】:

给定一个列表:

    private List<KeyValuePair<string, string>> KV_List = new List<KeyValuePair<string, string>>();
    void initList()
    {
        KV_List.Add(new KeyValuePair<string, string>("qwer", "asdf"));
        KV_List.Add(new KeyValuePair<string, string>("qwer", "ghjk"));
        KV_List.Add(new KeyValuePair<string, string>("zxcv", "asdf"));
        KV_List.Add(new KeyValuePair<string, string>("hjkl", "uiop"));
    }

(注意:键“qwer”有多个值,值“asdf”有多个键。)

1) 有没有比仅在 KeyValuePair 列表上执行 foreach 更好的方法来返回所有键的列表?

2) 同样,有没有比使用 foreach 更好的方法来返回给定键的所有值的列表?

3) 然后,返回给定值的键列表怎么样?

谢谢...

【问题讨论】:

  • 你能使用像this这样的多图吗?

标签: c# list keyvaluepair


【解决方案1】:
// #1: get all keys (remove Distinct() if you don't want it)
List<string> allKeys = (from kvp in KV_List select kvp.Key).Distinct().ToList();
// allKeys = { "qwer", "zxcv", "hjkl" }

// #2: get values for a key
string key = "qwer";
List<string> values = (from kvp in KV_List where kvp.Key == key select kvp.Value).ToList();
// values = { "asdf", "ghjk" }

// #3: get keys for a value
string value = "asdf";
List<string> keys = (from kvp in KV_List where kvp.Value == value select kvp.Key).ToList();
// keys = { "qwer", "zxcv" }

【讨论】:

  • 动态列表如何使用相同
【解决方案2】:

听起来你会从使用类似的东西中受益:

Dictionary<string, List<string>> kvlist;

kvlist["qwer"] = new List<string>();
kvlist["qwer"].Add("value1");
kvlist["qwer"].Add("value2");

foreach(var value in kvlist["qwer"]) {
    // do something
}

使用 Dictionary 和 List 创建基本的多值字典类会相对容易。

blog post 详细讨论了 Microsoft 可通过 NuGet 获得的 MultiDictionary 类型。

【讨论】:

  • 不幸的是,我无法控制列表(我必须“按原样播放”)...
  • 啊——太糟糕了。几个基于 Linq 的答案应该做你想做的事情(尽管它们对语法更友好,但它们不会比简单的循环更有效)。如果您可以确保列表始终按键值排序,那么您可以将性能从 O(n) 提高到 O(log n)。
  • 它通常是未排序的(按键或值),但是,列表中只有几千个条目。我可能会选择其中一个 linq 答案,对于将来查看代码的任何人来说,它们都会“看起来”更干净。 :)
【解决方案3】:

嗯,你肯定可以使用你的 LINQ。但这并不是“更好”(就性能而言),因为循环已经很快了。它可能更具可读性(个人喜好)。对于以下所有答案,请注意您需要导入 System.Linq 命名空间。它们还返回延迟加载的IEnumerable&lt;T&gt;(迭代时执行)。如果要返回具体列表,可以拨打.ToList() extension

有没有比只在 KeyValuePair 列表上执行 foreach 更好的方法来返回所有键的列表?

KV_List.Select(kvp => kvp.Key);

同样,有没有比使用 foreach 更好的方法来返回给定键的所有值的列表?

var theKeyToLookFor = "qwer";
KV_List.Where(kvp => kvp.Key == theKeyToLookFor).Select(kvp => kvp.Value);

然后,返回给定值的键列表怎么样?

var theValueToLookFor = "asdf";
KV_List.Where(kvp => kvp.Value == theValueToLookFor)
       .Select(kvp => kvp.Value)
       .ToList();

有关 LINQ 的更多信息,请查看LINQ (Language-Integrated Query)

【讨论】:

    【解决方案4】:

    您可以使用 System.Collection.Specialized 命名空间中的 NameValueCollection:

    NameValueCollection  KV_List = new NameValueCollection();
    
    KV_List.Add("qwer", "asdf");
    KV_List.Add("qwer", "ghjk");
    KV_List.Add("zxcv", "asdf");
    KV_List.Add("hjkl", "uiop");
    

    使用示例:

    string singleValue = KV_List["zxcv"];  // returns "asdf"
    string[] values = KV_List.GetValues("qwer");  // returns "asdf, "ghjk"
    string[] allKeys = KV_List.AllKeys;
    string[] allValues = KV_List.AllKeys;
    

    https://msdn.microsoft.com/en-us/library/system.collections.specialized.namevaluecollection%28v=vs.110%29.aspx

    【讨论】:

      【解决方案5】:

      我会在你的情况下使用ILookup&lt;K,V&gt;。它就像一本字典,但您可以使用相同的键获取 IEnumerable&lt;V&gt; 的值。

      ILookup<string, string> lookup = KV_List.ToLookup(x => x.Key, x => x.Value);
      IEnumerable<string> list = lookup["qwer"];
      foreach(string str in list)
      {
          Console.WriteLine(str);
      }
      

      或者干脆

      Console.WriteLine(string.Join(",", lookup["qwer"]));
      

      【讨论】:

        【解决方案6】:

        您是否正在阅读本文并想知道为什么有人让一些代码具有 IEnumerable> 而不是 Dictionary 但不想问,只想完成?

        if (collection == null)
            return null;
        
        return collection 
            .Where(z => z.Key == aThing)
            .Select(z => z.Value)
            .FirstOrDefault();
        

        【讨论】:

          【解决方案7】:

          1:

          KV_List.Select(i => i.Key).ToList()
          

          2:

          KV_List.Where(i => i.Key == filterByKey).Select(i => i.Value).ToList()
          

          3:

           KV_List.Where(i => i.Value == filterByValue).Select(i => i.Key).ToList()
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2010-12-20
            • 1970-01-01
            • 1970-01-01
            • 2010-11-22
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多