अद्यतन: दूसरों के रूप में उल्लेख किया है, ताकि एक शब्दकोश इस तरह से सही मायने में "प्रतिवर्ती" होने के लिए में, अपने List<string>
वस्तुओं में मूल्यों सभी के लिए अद्वितीय हो की जरूरत है; अन्यथा, आप अपने स्रोत शब्दकोश में प्रत्येक मान के लिए एक प्रविष्टि के साथ Dictionary<string, string>
नहीं बना सकते हैं, क्योंकि डुप्लिकेट कुंजी होगी।
उदाहरण:
var dictOne = new Dictionary<string, List<string>>
{
{ "A", new List<string> { "a1", "a2" } },
{ "B", new List<string> { "b1", "b2" } },
{ "C", new List<string> { "c1", "a2" } } // duplicate!
};
आपके पास (कम से कम) इस से निपटने के लिए दो विकल्प।
विकल्प 1: वास्तव में, डुप्लिकेट
आप यह सुनिश्चित करें कि हर List<string>
में हर तत्व है चाहते हो सकता है पर फेंक, अद्वितीय। इस मामले में, के साथ एक साधारण SelectMany
आपको जो चाहिए वह पूरा करेगा; ToDictionary
कॉल एक डुप्लिकेट मान का सामना पर एक ArgumentException
फेंक देगा: अपनी ही विधि में इस कार्यशीलता सार को
var dictTwo = dictOne
.SelectMany(kvp => kvp.Value.Select(s => new { Key = s, Value = kvp.Key }))
.ToDictionary(x => x.Key, x => x.Value);
सबसे सामान्य तरीके से (जो मन में आता) एक विस्तार विधि है कि किसी के लिए ऐसा करता है लागू करने के लिए किया जाएगा IDictionary<T, TEnumerable>
कार्यान्वयन जहां TEnumerable
लागू करता IEnumerable<TValue>
:
// Code uglified to fit within horizonal scroll area
public static Dictionary<T2, T1> ReverseDictionary<T1, T2, TEnumerable>(
this IDictionary<T1, TEnumerable> source) where TEnumerable : IEnumerable<T2>
{
return source
.SelectMany(e => e.Value.Select(s => new { Key = s, Value = e.Key }))
.ToDictionary(x => x.Key, x => x.Value);
}
उपरोक्त विधि में सामान्य प्रकार पैरामीटर की बदसूरत प्रसार सख्ती से Dictionary<T, List<T>>
के अलावा अन्य प्रकार के लिए अनुमति देने के लिए है: यह एकस्वीकार कर सकता है, उदाहरण के लिए, या SortedList<string, Queue<DateTime>>
- इसकी लचीलापन का प्रदर्शन करने के लिए केवल कुछ मनमाना उदाहरण हैं।
(एक परीक्षण कार्यक्रम इस विधि को दर्शाता हुआ इस उत्तर के नीचे स्थित है।) विकल्प 2: डुप्लिकेट छोड़ें
अपने List<string>
मूल्यों में डुप्लिकेट तत्वों को एक यथार्थवादी परिदृश्य है कि आप में सक्षम होना चाहते है अपवाद फेंकने के बिना संभालने के लिए, मेरा सुझाव है कि का उपयोग करने वाले दृष्टिकोण के लिए Gabe's excellent answer पर एक नज़र डालें (वास्तव में, गेबे भी एक लचीला दृष्टिकोण प्रदान करता है जो चयनकर्ता फ़ंक्शन के आधार पर इन दोनों मामलों में से किसी एक को कवर कर सकता है; हालांकि, यदि आप निश्चित रूप से डुप्लिकेट पर फेंकना चाहते हैं, मैं अभी भी abov का सुझाव देना चाहता हूँ ई दृष्टिकोण, क्योंकि यह GroupBy
का उपयोग करने से कुछ हद तक सस्ता होना चाहिए)।
उदाहरण कार्यक्रम
यहाँ एक छोटे से परीक्षण कार्यक्रम ऊपर को दर्शाता हुआ है एक साथ Dictionary<string, List<string>>
कोई डुप्लिकेट तत्वों को अपने List<string>
मूल्यों में पर विकल्प 1:
var dictOne = new Dictionary<string, List<string>>
{
{ "A", new List<string> { "a1", "a2" } },
{ "B", new List<string> { "b1", "b2" } },
{ "C", new List<string> { "c1" } }
};
// Using ReverseDictionary implementation described above:
var dictTwo = dictOne.ReverseDictionary<string, string, List<string>>();
foreach (var entry in dictTwo)
{
Console.WriteLine("{0}: {1}", entry.Key, entry.Value);
}
आउटपुट:
a1: A
a2: A
b1: B
b2: B
c1: C
क्या LINQ में ऐसा कोई विशिष्ट कारण है? –
@ माइकल शिममिन्स: अब मैं फ़ोरैच लूप का उपयोग कर रहा हूं। excecution प्रतिस्पर्धा करने के लिए और अधिक समय ले रहा है (मुझे 2000 से अधिक कुंजी और प्रत्येक मान (सूची) में कम से कम 5 आइटम हैं) –
मुझे संदेह है कि LINQ कोई तेज होगा, शायद धीमा हो जाएगा। –