कैसे एक IEnumerable <string> सॉर्ट करने के लिए


98

मैं IEnumerable<string>वर्णानुक्रम में कैसे छांट सकता हूं । क्या यह संभव है?

संपादित करें: मैं एक जगह समाधान कैसे लिखूंगा?

जवाबों:


155

उसी तरह से आप किसी अन्य गणना योग्य को छांट लेंगे:

var result = myEnumerable.OrderBy(s => s);

या

var result = from s in myEnumerable
             orderby s
             select s;

या (मामले की अनदेखी)

var result = myEnumerable.OrderBy(s => s,
                                  StringComparer.CurrentCultureIgnoreCase);

ध्यान दें कि, जैसा कि LINQ के साथ सामान्य है, यह एक नया IEnumerable <T> बनाता है, जो गणना करते समय, क्रमबद्ध क्रम में मूल IEnumerable <T> के तत्वों को वापस करता है। यह IEnumerable <T> इन-प्लेस को सॉर्ट नहीं करता है।


एक IEnumerable <T> केवल पढ़ने के लिए है, अर्थात्, आप केवल इसमें से तत्वों को पुनः प्राप्त कर सकते हैं, लेकिन इसे सीधे संशोधित नहीं कर सकते। यदि आप स्ट्रिंग्स के संग्रह को इन-प्लेस में सॉर्ट करना चाहते हैं, तो आपको मूल संग्रह को सॉर्ट करना होगा जो IEnumerable <string> को लागू करता है, या पहले एक सॉर्टेबल संग्रह में IEnumerable <string> को चालू करता है:

List<string> myList = myEnumerable.ToList();
myList.Sort();

आपकी टिप्पणी के आधार पर:

_components = (from c in xml.Descendants("component")
               let value = (string)c
               orderby value
               select value
              )
              .Distinct()
              .ToList();

या

_components = xml.Descendants("component")
                 .Select(c => (string)c)
                 .Distinct()
                 .OrderBy(v => v)
                 .ToList();

या (यदि आप बाद में सूची में और आइटम जोड़ना चाहते हैं और इसे क्रमबद्ध रखना चाहते हैं)

_components = xml.Descendants("component")
                 .Select(c => (string)c)
                 .Distinct()
                 .ToList();

_components.Add("foo");
_components.Sort();

या myEnumerable.OrderByDescending (s => s)।
ग्रज

तो, _कंप्यूटर = _कंपर्स।ऑर्डरबरी (s => s); ठीक हो जाएगा?
कैटज़िला

@ कैटज़िला: यह काम करना चाहिए, लेकिन आपकी वास्तविक समस्या को हल करने का सबसे अच्छा तरीका नहीं हो सकता है। _कंप्यूटर क्या है, आप इसे कहां से प्राप्त करते हैं, आप इसका उपयोग कैसे करते हैं?
dtb 20

1
: और मुझे इसे छाँटने की जरूरत है।
कैटजिला

2
OrderByलौटता है IOrderedEnumerable<T>IOrderedEnumerable<T>व्युत्पन्न IEnumerable<T>तो इसे इस्तेमाल किया जा सकता है IEnumerable<T>, लेकिन यह प्रकार का विस्तार करता है, उदाहरण के लिए, के उपयोग के लिए अनुमति देता है ThenBy
मैकिज हेहल

12

यह असंभव है, लेकिन ऐसा नहीं है।

मूल रूप से, किसी भी प्रकार के विधि अपने प्रतिलिपि करने के लिए जा रहा है IEnumerableएक में Listतरह, Listऔर फिर आप के लिए क्रमबद्ध सूची है, जो एक वापसी IEnumerableएक के रूप में भी IList

इसका मतलब है कि आप "अनन्त रूप से जारी रखें" की संपत्ति खो देते हैं IEnumerable, लेकिन फिर आप उस तरह से एक भी नहीं छाँट सकते।


7
सही पर। IEnumerable का उद्देश्य आपको एक श्रृंखला के लिए एक संभाल के साथ प्रस्तुत करना है जिसे आप "अगले" आइटम के लिए पूछना जारी रखकर, शुरुआत से अंत तक कर सकते हैं। इसका मतलब यह है कि सभी सामग्रियों को ज्ञात करने से पहले एक IEnumerable को आंशिक रूप से पुनरावृत्त किया जा सकता है; आपको यह जानने की जरूरत नहीं है कि जब तक आप उन सभी के माध्यम से नहीं चले जाते हैं। छंटनी (जैसे कई चीजें लिनक आपको करने देती हैं) को एक आदेशित सूची के रूप में पूरी श्रृंखला के ज्ञान की आवश्यकता होती है; वह आइटम जो किसी क्रमबद्ध श्रृंखला में पहली बार दिखाई देगा, वह श्रृंखला द्वारा अंतिम एक लौटाया जा सकता है, और आप यह नहीं जान पाएंगे कि जब तक आप यह नहीं जानते कि सभी आइटम क्या हैं।
कीथ्स


2

हम हमेशा इसे अंदर नहीं कर सकते, लेकिन हम इसका पता लगाते हैं कि यह कब संभव है:

IEnumerable<T> SortInPlaceIfCan(IEnumerable<T> src, IComparer<T> cmp)
{
  List<T> listToSort = (src is List<T>) ? (List<T>)src : new List<T>(src);
  listToSort.Sort(cmp);
  return listToSort;
}
IEnumerable<T> SortInPlaceIfCan(IEnumerable<T> src, Comparison<T> cmp)
{
  return SortInPlaceIfCan(src, new FuncComparer<T>(cmp));
}
IEnumerable<T> SortInPlaceIfCan(IEnumerable<T> src)
{
  return SortInPlaceIfCan(src, Comparer<T>.Default);
}

यह निम्नलिखित आसान संरचना का उपयोग करता है:

internal struct FuncComparer<T> : IComparer<T>
{
  private readonly Comparison<T> _cmp;
  public FuncComparer(Comparison<T> cmp)
  {
      _cmp = cmp;
  }
  public int Compare(T x, T y)
  {
      return _cmp(x, y);
  }
}

मुझे यकीन नहीं है कि मैं यह सुझाऊँगा। यदि आपके पास एक IEnumerable <T> है, लेकिन वास्तविक प्रकार नहीं है जो लागू करता है, तो आपको संभवतः इसे संशोधित नहीं करना चाहिए। Btw, Array.FunctorComparer <T> आंतरिक है।
dtb 20

हमारे पास जो कुछ भी है उसे संशोधित करने पर, मैंने उस स्थान पर खोज के प्रश्न में निहित होने के लिए ले लिया; इसका मतलब है कि यह। यह विधि नाम में "InPlaceInCan" होने का एक कारण है; विधि के नाम सर्वश्रेष्ठ प्रलेखन की तुलना में जोखिमों के बारे में और भी अधिक हो सकते हैं;) हाँ, Array.FunctorComparer <T> आंतरिक है, लेकिन यह तुच्छ है। मैंने इसे रखा क्योंकि यह सबसे अच्छा तरीका है कि मैं एक उदाहरण के बारे में सोच सकता हूं कि "आपके फ़ॉक्टर की तुलना आपके पास आपके सहायक कक्षाओं के सेट में है"।
जॉन हैना

@dtb दूसरे विचारों पर, अपने खुद के इस्तेमाल के लिए बदल गया (Array.FunctorComparer पर फिर से नज़र डालें और मैं वैसे भी मुझे पसंद करूँ!)
जॉन हैना

स्मार्ट विचार और नामकरण! लेकिन डबल कास्टिंग विरोधी पैटर्न में listToSort = (src is List<T>) ? (List<T>)src : new List<T>(src);क्यों? इसके बारे में क्या पसंद हैlistToSort = (src as List<T>); if (null == listToSort) listToSort = new List<T>(src);
जेरेन विर्ट प्लिमर्स

1
@JeroenWiertPluimers वहाँ हमेशा उदाहरण कोड के साथ समस्या है; शायद मैं सिर्फ इसलिए परेशान नहीं हुआ क्योंकि ऊपर वाला थोड़ा छोटा है और मैं मामले को ध्यान में रखना चाहता था, लेकिन उदाहरणों में बुरी आदतों को हतोत्साहित करना अच्छा है।
जॉन हन्ना
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.