মান দ্বারা অভিধান কী পান


361

সি # তে মান দ্বারা আমি কীভাবে একটি অভিধান কী পেতে পারি?

Dictionary<string, string> types = new Dictionary<string, string>()
{
            {"1", "one"},
            {"2", "two"},
            {"3", "three"}
};

আমি এরকম কিছু চাই:

getByValueKey(string value);

getByValueKey("one")ফিরে আসতে হবে "1"

এটি করার সর্বোত্তম উপায় কী? হতে পারে হ্যাশ টেবিল, সাজানো তালিকাগুলি?


9
নির্ভুল সদৃশ: স্ট্যাকওভারফ্লো.com
গাবে

আমি এই নিবন্ধটি আগে পড়েছি, তবে উত্তরটি সেখানে পাওয়া উচিত।
লোভিজি


7
এখানে স্বীকৃত উত্তরটি সদৃশ প্রশ্নের প্রত্যেকটির চেয়ে মারাত্মকভাবে ভাল is তবে সেই প্রশ্নটি পুরনো; জোন উত্তর দিলে সম্ভবত ল্যাম্বডা এক্সপ্রেশন উপস্থিত ছিল না।
শেঠ ব্যাটিন

5
অন্যটি বিশেষভাবে সম্বোধন করার পরে এই প্রশ্নটি পুনরায় খোলা। নেট 2.0, যদিও এটি জরুরী না। নেট ফ্রেমওয়ার্কের বর্তমান সংস্করণটির জন্য আরও ভাল উত্তর রয়েছে।
রাচেল

উত্তর:


645

মানগুলি অগত্যা অনন্য হতে হবে না তাই আপনাকে একটি অনুসন্ধান করতে হবে। আপনি এর মতো কিছু করতে পারেন:

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

মানগুলি যদি অনন্য হয় এবং পড়ার চেয়ে কম ঘন ঘন areোকানো হয় তবে একটি বিপরীত অভিধান তৈরি করুন যেখানে মানগুলি কী এবং কীগুলি মান হয়।


3
@ লবিজি: মনে রাখবেন যে লুপিং সমাধানে, অভিধানের শেষে যদি মানটি ঘটে থাকে তবে এটি খুঁজে পেতে এটি অন্য সমস্ত মানকে ছাড়িয়ে যেতে হবে। আপনার যদি বেশ কয়েকটি এন্ট্রি থাকে তবে এটি আপনার প্রোগ্রামকে কমিয়ে দেবে।
জাচ জনসন

2
@ জ্যাচ জনসন: ধন্যবাদ আমি আপনার সাথে একমত. এবং আপনার উত্তর আমি খুব পছন্দ করি। তবে আমার অভিধানে 8-10 এন্ট্রি রয়েছে। এবং এগুলি গতিশীলভাবে যুক্ত হয় না। এবং আমি মনে করি, এই উত্তরটি ব্যবহার করা খারাপ সমাধান নয়।
লোভিজি

4
আমি কি এখানে কিছু মিস করছি? উপরের কোডটি মানটি দেয়, কীটি নয়। প্রকারভেদ করা হবে না irst প্রথম অরডিফল্ট (x => x.Value == "এক") Key কী আরও উপযুক্ত হবে?
floele

19
সকলকে সতর্ক করে দেওয়া, গ্রহণযোগ্য উত্তরগুলি যেমন সম্পাদনাগুলির সাথে দাঁড়িয়ে থাকে তবে একটি ব্যতিক্রম ছুঁড়ে ফেলা হবে যদি ফার্স্টআরডিফল্ট কোনও মিল খুঁজে না পেয়ে এবং নাল বস্তুর "কী" অ্যাক্সেস করার চেষ্টা করে।
জিম ইয়ারব্রো

11
@ জিমায়ারব্রো: যেহেতু KeyValuePair<Tkey,Tvalue>একটি কাঠামো, সুতরাং একটি মান ধরণের, এটি কখনই হতে পারে না nullFirstOrDefaultসমস্ত ক্ষেত্র তাদের ডিফল্ট মান (যেমন nullস্ট্রিংগুলির জন্য বা 0 ints এর জন্য) দিয়ে শুরু করা হয় এমন একটি উদাহরণ ফিরে আসবে । সুতরাং আপনি একটি ব্যতিক্রম পাবেন না। তবে আপনি এটিও জানেন না যে আপনি কোনও মান খুঁজে পেয়েছেন কিনা, সুতরাং এই উত্তরটি মানটির অস্তিত্ব রাখে না।
টিম শেমলেটার

26

আপনি এটি করতে পারেন:

  1. KeyValuePair<TKey, TValue>অভিধানের সমস্তটি লুপ করে (অভিধানে যদি আপনার বেশ কয়েকটি এন্ট্রি থাকে তবে এটি একটি বিশাল পারফরম্যান্স হিট হবে)
  2. দুটি অভিধান ব্যবহার করুন, একটি মান থেকে কী ম্যাপিংয়ের জন্য একটি এবং কী-থেকে-মান মানচিত্রের জন্য (যা স্মৃতিতে দ্বিগুণ স্থান গ্রহণ করবে)।

কর্মক্ষমতা বিবেচনা না করা হলে পদ্ধতি 1 ব্যবহার করুন, মেমরিটি বিবেচনা না করা হলে পদ্ধতি 2 ব্যবহার করুন।

এছাড়াও, সমস্ত কী অবশ্যই অনন্য হতে হবে, তবে মানগুলি অনন্য হতে হবে না। নির্দিষ্ট মান সহ আপনার একাধিক কী থাকতে পারে।

কী-মূল্যের সম্পর্কটি আপনি বিপরীত করতে পারবেন না এমন কোনও কারণ আছে?


1
প্রোগ্রামগতভাবে বিপরীত অভিধান তৈরি করতে, আমাদের এখনও পদ্ধতি 1 ব্যবহার করা উচিত, তাই না?
কাইল

যদি এটি একটি সাধারণ ঘটনা হয় তবে আমি এই অদলবদলটিও সুপারিশ করব (আপনার শেষ প্রশ্নটি সম্পর্কিত)।
বোনজ024

3

আমি এমন পরিস্থিতিতে ছিলাম যেখানে লিনক বাঁধাই উপলভ্য ছিল না এবং লাম্বদা স্পষ্টভাবে প্রসারিত করতে হয়েছিল। এটি একটি সাধারণ ক্রিয়নের ফলাফল:

public static T KeyByValue<T, W>(this Dictionary<T, W> dict, W val)
{
    T key = default;
    foreach (KeyValuePair<T, W> pair in dict)
    {
        if (EqualityComparer<W>.Default.Equals(pair.Value, val))
        {
            key = pair.Key;
            break;
        }
    }
    return key;
}

নীচের মত এটি কল করুন:

public static void Main()
{
    Dictionary<string, string> dict = new Dictionary<string, string>()
    {
        {"1", "one"},
        {"2", "two"},
        {"3", "three"}
    };

    string key = KeyByValue(dict, "two");       
    Console.WriteLine("Key: " + key);
}

নেট 2.0 এবং অন্যান্য সীমাবদ্ধ পরিবেশে কাজ করে।


এটি একটি এক্সটেনশন পদ্ধতি হিসাবে যুক্ত করা আরও দুর্দান্ত :-)
ছাইম ফ্রেডম্যান

-1

সম্ভবত এর মতো কিছু:

foreach (var keyvaluepair in dict)
{
    if(Object.ReferenceEquals(keyvaluepair.Value, searchedObject))
    {
        //dict.Remove(keyvaluepair.Key);
        break;
    }
}

-1

আমি একটি ডাবল-লুকিং ক্লাস তৈরি করেছি:

/// <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;
            }
        }
    }

-3
types.Values.ToList().IndexOf("one");

মানসমূহ। টোললিস্ট () আপনার অভিধানের মানগুলিকে বস্তুর তালিকায় রূপান্তর করে। ইনডেক্সঅফ ("এক") আপনার নতুন তালিকার জন্য "একটি" সন্ধান করে এবং সূচকটি ফেরত দেয় যা অভিধানে কী / মান জোড়ার সূচির সাথে মিলবে।

এই পদ্ধতিটি অভিধান কীগুলির বিষয়ে চিন্তা করে না, এটি কেবল আপনি যে মানটির সন্ধান করছেন তা সূচকে ফিরে আসে।

মনে রাখবেন আপনার অভিধানে একাধিক "এক" মান থাকতে পারে। এবং সেই কারণেই কোনও "কী কী" পদ্ধতি নেই।


-4

কোডের নীচে কেবল তখনই কাজ করে যদি এতে অনন্য মূল্য ডেটা থাকে

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

3
-1 একটি পারফরম্যান্সের জন্য খুব বেশি কোড যা কিমি (যা আপনার আগে 6 বছর আগে পোস্ট করা হয়েছিল) এর শীর্ষ জবাবের চেয়ে খারাপ হবে । এই 2 টি তালিকা তৈরি করার জন্য আপনাকে কী এবং মানগুলির বৈশিষ্ট্যগুলি পূর্বাভাস দেওয়ার দরকার নেই (লিনকের টোলিস্টটি এটি আপনার জন্য করবে)। তদুপরি, আপনি যদি সূচিপত্র ব্যবহার করতে চলেছেন তবে আপনি কনটেনসভ্যালুতে কল এড়াতে পারতেন (এইভাবে একই কার্যের জন্য সমস্ত উপাদান যদিও 2 টি লুপ এড়ানো হবে)।
মারিয়ানো দেশানজে

2
এই পরামর্শটির কার্যকারিতাটি কেবলমাত্র ভয়াবহ। আপনি পাশাপাশি দুটি শব্দকোষ সহ একটি জেনেরিক ক্লাস তৈরি করতে পারেন। যার একটিতে কী 1 এবং কী 2 রয়েছে এবং অন্যটি কী 2 এবং কী 1 ধারণ করে। এইভাবে আপনি উভয়ই চাবি পেতে পারেন ... ভাল ... আপনার উত্তর প্রস্তাবিত সবকিছু।
ক্রিথিক

-12

আমার এটি করার খুব সহজ উপায় আছে। এটি আমার জন্য নিখুঁত কাজ করেছে।

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

3
দুঃখিত, তবে আপনার উত্তরটি প্রশ্নের সাথে মিলছে না। প্রশ্ন হল কিভাবে মান কী এটি সম্পর্কে, আপনার উত্তর শো মান ছিল: কী দ্বারা মান খোঁজার
ব্রীজ

1
প্রথম জিজ্ঞাসাটি পড়ুন, পরের বার
টমমিক্স 4'15

4
এবং এই মহিলারা, ভদ্রলোক, ঠিক কেন আমরা উত্তর পোস্ট করার আগে প্রশ্নগুলি পড়ি।
ক্রিথিক
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.