关于c#:按值获取字典键

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);

getByValueKey("one")必须返回"1"

最好的方法是什么?可能是哈希表,排序列表?


值不一定是唯一的,因此必须进行查找。你可以这样做:

1
var myKey = types.FirstOrDefault(x => x.Value =="one").Key;

如果值是唯一的,插入的频率低于读取的频率,那么创建一个反向字典,其中值是键,键是值。


你可以这样做:

  • 通过循环访问字典中的所有KeyValuePair(如果字典中有许多条目,这将是一个相当大的性能冲击)
  • 使用两个字典,一个用于值到键映射,一个用于键到值映射(这将占用内存空间的两倍)。
  • 如果性能不是考虑因素,则使用方法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);
    }