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