2010-10-28 22 views
48

को देखते हुए दोIEnumerable रों एक ही आकार के, मैं इसे कैसे एकDictionaryLINQ का उपयोग करने के लिए परिवर्तित कर सकते हैं?मानचित्र दो सूचियों

IEnumerable<string> keys = new List<string>() { "A", "B", "C" }; 
IEnumerable<string> values = new List<string>() { "Val A", "Val B", "Val C" }; 

var dictionary = /* Linq ? */; 

और उम्मीद उत्पादन होता है:

A: Val A 
B: Val B 
C: Val C 

मुझे आश्चर्य है कि अगर वहाँ इसे प्राप्त करने के कुछ आसान तरीका है।

और मुझे प्रदर्शन के बारे में चिंतित होना चाहिए? अगर मेरे पास बड़े संग्रह हैं तो क्या होगा?


मुझे नहीं पता कि क्या यह करने के लिए एक आसान तरीका है, वर्तमान में मैं इस तरह कर रहा हूँ:

मैं एक एक्सटेंशन विधि है कि होगा पाश IEnumerable मुझे तत्व और सूचकांक उपलब्ध कराने नंबर।

public static class Ext 
{ 
    public static void Each<T>(this IEnumerable els, Action<T, int> a) 
    { 
     int i = 0; 
     foreach (T e in els) 
     { 
      a(e, i++); 
     } 
    } 
} 

और मैं एक विधि है कि Enumerables की और सूचकांक के साथ पाश एक अन्य Enumerable पर बराबर तत्व को पुनः प्राप्त होगा।

public static Dictionary<TKey, TValue> Merge<TKey, TValue>(IEnumerable<TKey> keys, IEnumerable<TValue> values) 
{ 
    var dic = new Dictionary<TKey, TValue>(); 

    keys.Each<TKey>((x, i) => 
    { 
     dic.Add(x, values.ElementAt(i)); 
    }); 

    return dic; 
} 

तब मुझे यह पसंद का उपयोग करें:

IEnumerable<string> keys = new List<string>() { "A", "B", "C" }; 
IEnumerable<string> values = new List<string>() { "Val A", "Val B", "Val C" }; 

var dic = Util.Merge(keys, values); 

और उत्पादन सही है:

A: Val A 
B: Val B 
C: Val C 

उत्तर

101
.NET 4.0 (या आरएक्स से System.Interactive के 3.5 संस्करण) के साथ

, आप Zip() का उपयोग कर सकते हैं:

var dic = keys.Zip(values, (k, v) => new { k, v }) 
       .ToDictionary(x => x.k, x => x.v); 
+0

। ज़िप के लिए अंगूठे। खुशी है कि यह इसे बीसीएल में बना दिया गया है। मेरे पास कुछ समय के लिए मेरा अपना संस्करण है। – spender

+1

@ स्पेंडर - यहां तक ​​कि यदि आपने अपना खुद का बना लिया है, तो भी मैं इसे [एरिक लिपर्ट्स ब्लॉग] से ले जाऊंगा (http://blogs.msdn.com/b/ericlippert/archive/2009/05/07/zip-me-up। एएसपीएक्स) – Oliver

+1

दयालुता 'ज़िप' विधि की आवश्यकता है। यदि केवल अधिक स्थैतिक रूप से टाइप की गई भाषाएं सामान्य वैरैडिक पैरामीटर का समर्थन करती हैं, तो 'चयन करें' इसे संभालेगा (जैसे योजना में 'मानचित्र')। – leppie

20

या आपके विचार के आधार पर, LINQ में Select() का एक अधिभार शामिल है जो सूचकांक प्रदान करता है। तथ्य यह है कि values सूचकांक द्वारा पहुँच का समर्थन के साथ संयुक्त, एक कर सकता है निम्नलिखित:

var dic = keys.Select((k, i) => new { k, v = values[i] }) 
       .ToDictionary(x => x.k, x => x.v); 

(valuesList<string> के रूप में रखा जाता है, वह यह है कि ... अगर)

+0

ओह, सुंदर! मैं इसके लिए बिल्कुल देख रहा था। लिंक आसान है, लेकिन जिस कोड को आप लिखना चाहते हैं वह वास्तव में भ्रमित आईएमओ दिखता है। – Nyerguds

7

मैं इस दृष्टिकोण की तरह है:

var dict = 
    Enumerable.Range(0, keys.Length).ToDictionary(i => keys[i], i => values[i]); 
0

आप MoreLINQ का उपयोग करते हैं, आप भी यह पूर्व में बने KeyValuePair रों पर ToDictionary विस्तार विधि है का उपयोग कर सकते हैं:

var dict = Enumerable 
    .Zip(keys, values, (key, value) => KeyValuePair.Create(key, value)) 
    .ToDictionary(); 

यह भी ध्यान दिया जाना चाहिए कि विभिन्न लंबाई के इनपुट संग्रह के खिलाफ Zip एक्सटेंशन विधि सुरक्षित है।

संबंधित मुद्दे