get dictionary key by value
如何在C中按值获取字典键?
1 2 3 4 5 6 | Dictionary<string, string> types = new Dictionary<string, string>() { {"1","one"}, {"2","two"}, {"3","three"} }; |
我想要这样的东西:
1 | getByValueKey(string value); |
最好的方法是什么?可能是哈希表,排序列表?
值不一定是唯一的,因此必须进行查找。你可以这样做:
1 | var myKey = types.FirstOrDefault(x => x.Value =="one").Key; |
如果值是唯一的,插入的频率低于读取的频率,那么创建一个反向字典,其中值是键,键是值。
你可以这样做:
如果性能不是考虑因素,则使用方法1;如果内存不是考虑因素,则使用方法2。
此外,所有键都必须是唯一的,但不要求值是唯一的。可以有多个具有指定值的键。
您是否有任何理由不能逆转键值关系?
我遇到的情况是Linq绑定不可用,必须显式扩展lambda。它产生了一个简单的函数:
1 2 3 4 5 6 7 8 9 10 11 12 13 | public static string KeyByValue(Dictionary<string, string> dict, string val) { string key = null; foreach (KeyValuePair<string, string> pair in dict) { if (pair.Value == val) { key = pair.Key; break; } } return key; } |
如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 | public static void Main() { Dictionary<string, string> dict = new Dictionary<string, string>() { {"1","one <div class="suo-content">[collapse title=""]<ul><li>将其添加为扩展方法更为合适:-)</li></ul>[/collapse]</div><hr> <p> I have created a double-lookup class: </p> [cc lang="csharp"]/// <summary> /// dictionary with double key lookup /// </summary> /// <typeparam name="T1">primary key</typeparam> /// <typeparam name="T2">secondary key</typeparam> /// <typeparam name="TValue">value type</typeparam> public class cDoubleKeyDictionary<T1, T2, TValue> { private struct Key2ValuePair { internal T2 key2; internal TValue value; } private Dictionary<T1, Key2ValuePair> d1 = new Dictionary<T1, Key2ValuePair>(); private Dictionary<T2, T1> d2 = new Dictionary<T2, T1>(); /// <summary> /// add item /// not exacly like add, mote like Dictionary[] = overwriting existing values /// </summary> /// <param name="key1"></param> /// <param name="key2"></param> public void Add(T1 key1, T2 key2, TValue value) { lock (d1) { d1[key1] = new Key2ValuePair { key2 = key2, value = value, }; d2[key2] = key1; } } /// <summary> /// get key2 by key1 /// </summary> /// <param name="key1"></param> /// <param name="key2"></param> /// <returns></returns> public bool TryGetValue(T1 key1, out TValue value) { if (d1.TryGetValue(key1, out Key2ValuePair kvp)) { value = kvp.value; return true; } else { value = default; return false; } } /// <summary> /// get key1 by key2 /// </summary> /// <param name="key2"></param> /// <param name="key1"></param> /// <remarks> /// 2x O(1) operation /// </remarks> /// <returns></returns> public bool TryGetValue2(T2 key2, out TValue value) { if (d2.TryGetValue(key2, out T1 key1)) { return TryGetValue(key1, out value); } else { value = default; return false; } } /// <summary> /// get key1 by key2 /// </summary> /// <param name="key2"></param> /// <param name="key1"></param> /// <remarks> /// 2x O(1) operation /// </remarks> /// <returns></returns> public bool TryGetKey1(T2 key2, out T1 key1) { return d2.TryGetValue(key2, out key1); } /// <summary> /// get key1 by key2 /// </summary> /// <param name="key2"></param> /// <param name="key1"></param> /// <remarks> /// 2x O(1) operation /// </remarks> /// <returns></returns> public bool TryGetKey2(T1 key1, out T2 key2) { if (d1.TryGetValue(key1, out Key2ValuePair kvp1)) { key2 = kvp1.key2; return true; } else { key2 = default; return false; } } /// <summary> /// remove item by key 1 /// </summary> /// <param name="key1"></param> public void Remove(T1 key1) { lock (d1) { if (d1.TryGetValue(key1, out Key2ValuePair kvp)) { d1.Remove(key1); d2.Remove(kvp.key2); } } } /// <summary> /// remove item by key 2 /// </summary> /// <param name="key2"></param> public void Remove2(T2 key2) { lock (d1) { if (d2.TryGetValue(key2, out T1 key1)) { d1.Remove(key1); d2.Remove(key2); } } } /// <summary> /// clear all items /// </summary> public void Clear() { lock (d1) { d1.Clear(); d2.Clear(); } } /// <summary> /// enumerator on key1, so we can replace Dictionary by cDoubleKeyDictionary /// </summary> /// <param name="key1"></param> /// <returns></returns> public TValue this[T1 key1] { get => d1[key1].value; } /// <summary> /// enumerator on key1, so we can replace Dictionary by cDoubleKeyDictionary /// </summary> /// <param name="key1"></param> /// <returns></returns> public TValue this[T1 key1, T2 key2] { set { lock (d1) { d1[key1] = new Key2ValuePair { key2 = key2, value = value, }; d2[key2] = key1; } } } |
可能是这样的:
1 2 3 4 5 6 7 8 | foreach (var keyvaluepair in dict) { if(Object.ReferenceEquals(keyvaluepair.Value, searchedObject)) { //dict.Remove(keyvaluepair.Key); break; } } |
以下代码仅在包含唯一值数据时有效
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | public string getKey(string Value) { if (dictionary.ContainsValue(Value)) { var ListValueData=new List<string>(); var ListKeyData = new List<string>(); var Values = dictionary.Values; var Keys = dictionary.Keys; foreach (var item in Values) { ListValueData.Add(item); } var ValueIndex = ListValueData.IndexOf(Value); foreach (var item in Keys) { ListKeyData.Add(item); } return ListKeyData[ValueIndex]; } return string.Empty; } |
1 | types.Values.ToList().IndexOf("one"); |
values.tolist()将字典值转换为对象列表。index of("one")搜索新列表,查找"one",并返回与字典中键/值对的索引匹配的索引。
此方法不关心字典键,它只返回您要查找的值的索引。
请记住,字典中可能有多个"一"值。这就是为什么没有"get key"方法的原因。
我有非常简单的方法来做这个。这对我来说很完美。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | Dictionary<string, string> types = new Dictionary<string, string>(); types.Add("1","one"); types.Add("2","two"); types.Add("3","three"); Console.WriteLine("Please type a key to show its value:"); string rLine = Console.ReadLine(); if(types.ContainsKey(rLine)) { string value_For_Key = types[rLine]; Console.WriteLine("Value for" + rLine +" is" + value_For_Key); } |