Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如果值是列表形式,如何从字典中获取键?_C#_Dictionary - Fatal编程技术网

C# 如果值是列表形式,如何从字典中获取键?

C# 如果值是列表形式,如何从字典中获取键?,c#,dictionary,C#,Dictionary,我有一本名为dict_id_names的字典: 假设字典包含3个键值对: id=1:列表包含Robin、Rahul、Adam、Akhtar、 id=2:列表包含名称Sun、Mon、Adam、 id=3:列表包含名称a、b、c 现在我的问题是,如果我只有名字Adam,那么在上述情况下,如何从字典中获得相应的键1和键2?您可以使用LINQ: var keyValsWithAdamValue = dict_id_names.Where(kv => kv.Value.Contains("Adam"

我有一本名为dict_id_names的字典:

假设字典包含3个键值对:

id=1:列表包含Robin、Rahul、Adam、Akhtar、

id=2:列表包含名称Sun、Mon、Adam、

id=3:列表包含名称a、b、c

现在我的问题是,如果我只有名字Adam,那么在上述情况下,如何从字典中获得相应的键1和键2?

您可以使用LINQ:

var keyValsWithAdamValue = dict_id_names.Where(kv => kv.Value.Contains("Adam"));

foreach(var kv in keyValsWithAdamValue)
    Console.WriteLine("{0}|{1}", kv.Key, String.Join(",", kv.Value));
如果只需要ID,可以选择它们并使用ToList/ToArray创建集合:

List<int> idsWithAdamInList = dict_id_names
    .Where(kv => kv.Value.Contains("Adam"))
    .Select(kv => kv.Key)
    .ToList();
请注意,这种方法类似于字典上的循环。如果您正在枚举字典,那么它的快速查找性能将不会给您带来好处。它不是为这个目的设计的。但是,如果在这种情况下性能不是那么重要,那么它是简单易读的代码,也是完美的

string name = "Adam";
foreach(int key in dict_id_names.Keys)
{
    List<string> valueList = dict_id_names[key];

    if(valueList.Contains(name);
       Console.WriteLine(id);
}

这应该会有所帮助。

您可以使用以下LINQ查询:

int[] ids = dict_id_names
                    .Where(pair => pair.Value.Contains("Adam"))
                    .Select(pair => pair.Key)
                    .ToArray();

Console.WriteLine(String.Join(',', ids)); // 1,2
它将产生一个数组[1,2],因为这两个字典条目的字符串列表中都包含Adam-

var dict_id_names= new Dictionary<int,List<string>>();
dict_id_names.Add(1, new List<string> { "Robin", "Rahul", "Adam", "Akhtar" });
var id = dict_id_names.Where(a => a.Value.Contains("Adam")).FirstOrDefault().Key;

我只是想提供一个不同的视角,以便于比较

假设您经常进行这种反向查找,并且希望它比ON操作更好

您可以使用两个词典而不是一个词典来实现这一点。为了简化本例中的内容,我将使用Microsoft的预发布多值字典,您可以通过NuGet获得该字典

此方法产生O1查找:

using System;
using System.Collections.Generic;
using System.Linq;

namespace Demo
{
    internal class Program
    {
        public static void Main()
        {
            var names = new Names();

            names.Add(1, "Robin");
            names.Add(1, "Rahul");
            names.Add(1, "Adam");
            names.Add(1, "Akhtar");

            names.Add(2, "Sun");
            names.Add(2, "Mon");
            names.Add(2, "Adam");

            names.Add(3, "a");
            names.Add(3, "a");
            names.Add(3, "c");

            Console.WriteLine("IDs for Adam:");

            foreach (int id in names.IdsOf("Adam"))
                Console.WriteLine(id);
        }

        public sealed class Names
        {
            readonly MultiValueDictionary<int, string> names = new MultiValueDictionary<int, string>();
            readonly MultiValueDictionary<string, int> lookup = new MultiValueDictionary<string, int>();

            public void Add(int id, string name)
            {
                names.Add(id, name);
                lookup.Add(name, id);
            }

            public IEnumerable<int> IdsOf(string name)
            {
                IReadOnlyCollection<int> result;

                if (lookup.TryGetValue(name, out result))
                    return result;
                else
                    return Enumerable.Empty<int>();
            }

            public IEnumerable<string> NamesOf(int id)
            {
                IReadOnlyCollection<string> result;

                if (names.TryGetValue(id, out result))
                    return result;
                else
                    return Enumerable.Empty<string>();
            }
        }
    }
}

是否要求反向查找与普通字典一样为~O1?请注意,下面的所有答案都涉及到字典的完整扫描。是的,我以前尝试过这个方法,但是是否有其他方法或方法不需要完全扫描字典?
using System;
using System.Collections.Generic;
using System.Linq;

namespace Demo
{
    internal class Program
    {
        public static void Main()
        {
            var names = new Names();

            names.Add(1, "Robin");
            names.Add(1, "Rahul");
            names.Add(1, "Adam");
            names.Add(1, "Akhtar");

            names.Add(2, "Sun");
            names.Add(2, "Mon");
            names.Add(2, "Adam");

            names.Add(3, "a");
            names.Add(3, "a");
            names.Add(3, "c");

            Console.WriteLine("IDs for Adam:");

            foreach (int id in names.IdsOf("Adam"))
                Console.WriteLine(id);
        }

        public sealed class Names
        {
            readonly MultiValueDictionary<int, string> names = new MultiValueDictionary<int, string>();
            readonly MultiValueDictionary<string, int> lookup = new MultiValueDictionary<string, int>();

            public void Add(int id, string name)
            {
                names.Add(id, name);
                lookup.Add(name, id);
            }

            public IEnumerable<int> IdsOf(string name)
            {
                IReadOnlyCollection<int> result;

                if (lookup.TryGetValue(name, out result))
                    return result;
                else
                    return Enumerable.Empty<int>();
            }

            public IEnumerable<string> NamesOf(int id)
            {
                IReadOnlyCollection<string> result;

                if (names.TryGetValue(id, out result))
                    return result;
                else
                    return Enumerable.Empty<string>();
            }
        }
    }
}