2008-09-19 12 views
12

पायथन में एक बहुत साफ समारोह zip कहा जाता है जो एक ही समय में दो सूचियों के माध्यम से पुनरावृति करने के लिए इस्तेमाल किया जा सकता है:क्या नेट में कोई ज़िप-जैसी विधि है?

list1 = [1, 2, 3] 
list2 = ["a", "b", "c"] 
for v1, v2 in zip(list1, list2): 
    print v1 + " " + v2 

उपरोक्त कोड का उत्पादन करना चाहिए निम्नलिखित:

1 a 
2 b 
3 c

मुझे आश्चर्य है यदि कोई तरीका है जैसे नेट में उपलब्ध है? मैं इसे खुद लिखने के बारे में सोच रहा हूं, लेकिन अगर यह पहले से ही उपलब्ध है तो कोई बात नहीं है।

+0

कोई समझा सकते हैं कि यह कैसे सिर्फ एक तरह पाश "के लिए" से अलग है: (वर के लिए मैं; ;) {var x = arr1 [i]; var y = arr2 [i]; } मुझे लगता है कि एक जटिल अंतर है जिसे मैं यहां नहीं देख रहा हूं। –

+2

एलन, कम से कम सरणी के लिए नहीं है। हालांकि, ज़िप कुछ भी काम करेगा जो आप फिर से कर सकते हैं, न केवल उदा। सरणियों। –

+0

एलन: ज़िप() एक अभिव्यक्ति है। आपका विकल्प कोड का एक ब्लॉक है। – recursive

उत्तर

25

अपडेट::

आप कुछ इस तरह उपयोग कर सकते हैं यह सी # में निर्मित है 4 System.Linq.Enumerable.Zip Method

यहाँ के रूप में एक सी # 3 संस्करण है:

IEnumerable<TResult> Zip<TResult,T1,T2> 
    (IEnumerable<T1> a, 
    IEnumerable<T2> b, 
    Func<T1,T2,TResult> combine) 
{ 
    using (var f = a.GetEnumerator()) 
    using (var s = b.GetEnumerator()) 
    { 
     while (f.MoveNext() && s.MoveNext()) 
      yield return combine(f.Current, s.Current); 
    } 
} 

छोड़ा सी # 2 संस्करण क्योंकि यह अपनी उम्र दिखा रहा था।

+0

का उपयोग करने के लिए पेयर <,> को परिभाषित करने के लिए अच्छा होगा या परिणाम चयनकर्ता के रूप में कार्य करने वाला एक अतिरिक्त पैरामीटर लें। –

+0

वाह, मैं आश्चर्यचकित हूं। जबकि मैं अपना जवाब लिख रहा था, आप लगभग 100% समान समाधान प्रदान करते हैं :) – aku

+0

यह "var" कीवर्ड (यदि आप 3.5 पर थे) का उपयोग करने के लिए आदर्श स्थितियों में से एक है: foreach (ज़िप में जोड़ों (इंट्स, तार)) आप जोड़ी घोषणा का शोर खो देते हैं जो मेरे लिए अनियंत्रित है। –

5

नहीं, .NET में ऐसा कोई फ़ंक्शन नहीं है। आपने अपना खुद का रोल आउट किया है। ध्यान दें कि सी # tuples का समर्थन नहीं करता है, तो अजगर की तरह वाक्यविन्यास चीनी भी गायब है।

class Pair<T1, T2> 
{ 
    public T1 First { get; set;} 
    public T2 Second { get; set;} 
} 

static IEnumerable<Pair<T1, T2>> Zip<T1, T2>(IEnumerable<T1> first, IEnumerable<T2> second) 
{ 
    if (first.Count() != second.Count()) 
     throw new ArgumentException("Blah blah"); 

    using (IEnumerator<T1> e1 = first.GetEnumerator()) 
    using (IEnumerator<T2> e2 = second.GetEnumerator()) 
    { 
     while (e1.MoveNext() && e2.MoveNext()) 
     { 
      yield return new Pair<T1, T2>() {First = e1.Current, Second = e2.Current}; 
     } 
    } 
} 

... 

var ints = new int[] {1, 2, 3}; 
var strings = new string[] {"A", "B", "C"}; 

foreach (var pair in Zip(ints, strings)) 
{ 
    Console.WriteLine(pair.First + ":" + pair.Second); 
} 
+0

+1 का उपयोग कर-ब्लॉक –

8

जहां तक ​​मुझे पता है कि वहां नहीं है। मैं खुद के लिए एक (और साथ ही कुछ अन्य उपयोगी एक्सटेंशन और उन्हें एक परियोजना Codeplex पर NExtension कहा जाता है में डाल लिखा था।

जाहिर नेट के लिए समानांतर एक्सटेंशन एक ज़िप समारोह है।

यहाँ से एक सरलीकृत संस्करण है NExtension (लेकिन इसे और अधिक उपयोगी विस्तार के तरीकों के लिए बाहर की जाँच करें):

public static IEnumerable<TResult> Zip<T1, T2, TResult>(this IEnumerable<T1> source1, IEnumerable<T2> source2, Func<T1, T2, TResult> combine) 
{ 
    using (IEnumerator<T1> data1 = source1.GetEnumerator()) 
    using (IEnumerator<T2> data2 = source2.GetEnumerator()) 
     while (data1.MoveNext() && data2.MoveNext()) 
     { 
      yield return combine(data1.Current, data2.Current); 
     } 
} 

उपयोग:

int[] list1 = new int[] {1, 2, 3}; 
string[] list2 = new string[] {"a", "b", "c"}; 

foreach (var result in list1.Zip(list2, (i, s) => i.ToString() + " " + s)) 
    Console.WriteLine(result); 
+0

अच्छा जवाब। आपको सी # 3.0 – Coincoin

+0

में फ़ंक्शन का उपयोग करने का एक उदाहरण जोड़ना चाहिए, स्वीकृत उत्तर के रूप में यहां एक ही टिप्पणी, आईन्यूमेरेटर IDISposable है, आपको कुछ उपयोग-ब्लॉक जोड़ना चाहिए। –

2

नहीं है एफ # में भी एक:

देना ज़िप किया गया = Seq.zip firstEnumeration secondEnumation

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