2012-03-21 18 views
8

LINQ का उपयोग कर दो आदेशित अनुक्रमों को मर्ज करने का कोई आसान तरीका है?

IEnumerable<T> first; 
IEnumerable<T> second; 

को देखते हुए और कहा कि first और second दोनों एक comparer Func<T, T, int> कि समानता के लिए 0 देता है, -1 जब पहली "छोटे" और 1 है दूसरी "छोटे" है जब द्वारा आदेश दिया गया है।

क्या LINQ का उपयोग करके दो अनुक्रमों को मर्ज करने के लिए एक सीधा-आगे तरीका है जिससे परिणामस्वरूप अनुक्रम भी एक ही तुलनाकर्ता द्वारा आदेश दिया जाता है?

हम वर्तमान में एक हाथ से तैयार किए गए एल्गोरिदम का उपयोग कर रहे हैं जो काम करता है, लेकिन सीधे-आगे LINQ कथन की पठनीयता बेहतर होगी।

+2

[अनुसार क्रमबद्ध विलय IEnumerable के लिए सबसे कुशल एल्गोरिथ्म] के संभावित डुप्लिकेट (http://stackoverflow.com/questions/ तरह

public static IEnumerable<T> MergeSorted<T>(this IEnumerable<T> first, IEnumerable<T> second, Func<T, T, int> comparer) { using (var firstEnumerator = first.GetEnumerator()) using (var secondEnumerator = second.GetEnumerator()) { var elementsLeftInFirst = firstEnumerator.MoveNext(); var elementsLeftInSecond = secondEnumerator.MoveNext(); while (elementsLeftInFirst || elementsLeftInSecond) { if (!elementsLeftInFirst) { do { yield return secondEnumerator.Current; } while (secondEnumerator.MoveNext()); yield break; } if (!elementsLeftInSecond) { do { yield return firstEnumerator.Current; } while (firstEnumerator.MoveNext()); yield break; } if (comparer(firstEnumerator.Current, secondEnumerator.Current) < 0) { yield return firstEnumerator.Current; elementsLeftInFirst = firstEnumerator.MoveNext(); } else { yield return secondEnumerator.Current; elementsLeftInSecond = secondEnumerator.MoveNext(); } } } } 

प्रयोग कुछ 2767007/सबसे कुशल-एल्गोरिदम-के-विलय-क्रमबद्ध-ienumerablet) – Jon

+0

क्या आपने अपने हाथ से तैयार किए गए एल्गोरिदम को एक अलग विधि में निकाला है? पठनीयता में सुधार करने का यह सबसे आसान तरीका होगा। – phoog

+2

यदि आपको पठनीयता (प्रदर्शन पर) पसंद है तो: 'var दोनों = first.Union (second)। ऑर्डर बी (तुलनात्मक); ' –

उत्तर

11

आप इसके लिए एक विस्तार विधि परिभाषित कर सकते हैं।

var s1 = new[] { 1, 3, 5, 7, 9 }; 
var s2 = new[] { 2, 4, 6, 6, 6, 8 }; 

var merged = s1.MergeSorted(s2, (a, b) => a > b ? 1 : -1).ToList(); 

Console.WriteLine(string.Join(", ", merged)); 

आउटपुट::

1, 2, 3, 4, 5, 6, 6, 6, 7, 8, 9 
+2

एकल-पास कोड का एक ठोस टुकड़ा - धन्यवाद! –

+0

पैरामीटर 'तुलनाकर्ता' को शून्य (वैकल्पिक पैरामीटर) होने की अनुमति दी जा सकती है और 'तुलनात्मक पर सेट की जा सकती है। अगर यह शून्य है तो .efault.Compare' पर सेट करें। – springy76

0

मुझे लगता है कि सूची में पहली संख्या बदलने और इस सूची में दूसरी वस्तु जोड़ने के बाद सॉर्ट करने से चाल चल जाएगी।

 IEnumerable<int> first = new List<int>(){1,3}; 
     IEnumerable<int> second = new List<int>(){2,4}; 

     var temp = first.ToList(); 
     temp.AddRange(second); 


     temp.Sort(new Comparison<int>(comparer)); // where comparer is Func<T,T,int> 
+7

यह कार्यान्वयन ओ (एन) अतिरिक्त भंडारण में है, ओ (एन एलजी एन) समय के सामान्य मामले में और ओ (एन^2) समय के सबसे खराब मामले में। एक एल्गोरिदम है जो ओ (1) दोनों अतिरिक्त भंडारण और समय में ओ (एन) है। –

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