C # में किसी सूची के पहले N तत्वों को कैसे प्राप्त करें?


384

मैं अपने प्रोजेक्ट में बस शेड्यूल को क्वेरी करने के लिए Linq का उपयोग करना चाहूंगा, ताकि किसी भी समय मुझे अगले 5 बस आगमन समय मिल सके। मैं अपनी क्वेरी को पहले 5 परिणामों तक कैसे सीमित कर सकता हूं?

अधिक सामान्यतः, मैं C # में किसी सूची का टुकड़ा कैसे ले सकता हूं? (पायथन में मैं mylist[:5]पहले 5 तत्वों को प्राप्त करने के लिए उपयोग करूँगा ।)

जवाबों:


706
var firstFiveItems = myList.Take(5);

या टुकड़ा करने के लिए:

var secondFiveItems = myList.Skip(5).Take(5);

और निश्चित रूप से अक्सर किसी प्रकार के आदेश के अनुसार पहले पांच आइटम प्राप्त करना सुविधाजनक होता है:

var firstFiveArrivals = myList.OrderBy(i => i.ArrivalTime).Take(5);

87
क्या केवल अपवाद हैं, उदाहरण के लिए, सूची में 3 आइटम? या 5 के रूप में कई ले जाएगा?
बोबेक

87
@ बॉब: यह अपवाद नहीं है। यदि पर्याप्त तत्व नहीं हैं तो यह केवल वही देता है जो उसके पास है।
जोशुआ पेच

1
वास्तव में, कोई अपवाद नहीं छोड़ें छोड़ें और संयुक्त रूप से मेरी समस्या को हल करें क्योंकि मैं प्रति बैच में कोई सामान्य संग्रह और प्रक्रिया x आइटम लेना चाहता था
जोहानलर्सन

यह ध्यान दिया जाना चाहिए कि .Take(n)एक TakeIterator लौटाता है; यह इसमें nतत्वों के साथ एक सूची वापस नहीं करता है (यह मानते हुए कि कई उपलब्ध हैं)। का प्रयोग करें .ToArray()या .ToList()के परिणाम पर Takeएक ठोस सरणी या सूची प्राप्त करने के।
एंड्रयू वेब

69

यदि किसी को दिलचस्पी है (भले ही प्रश्न इस संस्करण के लिए नहीं पूछता है), सी # 2 में होगा: (मैंने कुछ सुझावों का पालन करते हुए उत्तर को संपादित किया है)

myList.Sort(CLASS_FOR_COMPARER);
List<string> fiveElements = myList.GetRange(0, 5);

शायद एक अनाम विधेय भी जोड़ सकते हैं?
अलेक्सईएमके

2
सूची <टी> .Sort रिटर्न शून्य; आपको सॉर्ट करने की आवश्यकता होगी, फिर अलग से GetRange का उपयोग करें। आप CLASS_FOR_COMPARER की आवश्यकता को हटाने के लिए एक तुलना <T> अनाम विधि का उपयोग कर सकते हैं।
मार्क Gravell

@AlexeyMK - यदि आप एक तुलना <टी> मतलब है, नहीं एक विधेय (विधेय <टी>) - एक विधेय फिल्टर डेटा लिए किया जाता है
मार्क Gravell

मेरा मानना ​​है कि यह उत्तर अब भी उपयोगी है, 10 साल और बाद में कई सी # संस्करण। विशिष्ट मामले के लिए जहां आपके पास एक सूची है। खासकर यदि आप कई वस्तुओं को छोड़ रहे हैं। उदाहरण के लिए, आपके पास एक लाख वस्तुओं की सूची है, और आप उनमें से 5 का एक टुकड़ा चाहते हैं, जो सूची में है। GetRange वास्तव में जानता है कि उन्हें हड़पने के लिए कहाँ जाना है। मुझे नहीं पता कि क्या Skip+ Takeस्मार्ट के रूप में है, या क्या यह स्किप की गई वस्तुओं से अधिक है। और मुझे यह जानने की आवश्यकता नहीं है - मैं सिर्फ गेटरेंज (जब एक सूची दी गई है) का उपयोग करता हूं। बस सुनिश्चित करें कि आपको एहसास है कि दूसरा पैरामीटर गिनती ( पिछले सूचकांक के बजाय ) है।
टूलमेकरसैट

इसके बारे .Take(n)में अच्छी बात यह है कि अगर आपको इस nपर काम करने वाले अनुक्रम में तत्वों से कम है तो आपको चिंता करने की ज़रूरत नहीं है । इसके साथ समस्या List<T>.GetRange(0, count)यह है कि आपको चिंता करने की ज़रूरत नहीं है .... आपको एक आइटम ArgumentExceptionनहीं मिलेगा count
एंड्रयू वेब

5

जैसे paginationआप लेने के लिए फॉर्मूले के नीचे उपयोग कर सकते हैं slice of list or elements:

var slice = myList.Skip((pageNumber - 1) * pageSize)
                  .Take(pageSize);

उदाहरण 1: पहले पांच आइटम

var pageNumber = 1;
var pageSize = 5;

उदाहरण 2: दूसरा पांच आइटम

var pageNumber = 2;
var pageSize = 5;

उदाहरण 3: तीसरे पाँच आइटम

var pageNumber = 3;
var pageSize = 5;

यदि आप मापदंडों को तैयार करने के लिए नोटिस कर रहे हैं pageSize = 5और pageNumberबदल रहे हैं, यदि आप बदलने वाले आइटमों की संख्या को बदलना चाहते हैं pageSize


1

पहले 5 तत्वों को लेने के लिए इस तरह की अभिव्यक्ति का बेहतर उपयोग करें:

var firstFiveArrivals = myList.Where([EXPRESSION]).Take(5);

या

var firstFiveArrivals = myList.Where([EXPRESSION]).Take(5).OrderBy([ORDER EXPR]);

यह ऑर्डर किए गए संस्करण की तुलना में अधिक तेज़ होगा, क्योंकि LINQ इंजन देरी निष्पादन के कारण सभी सूची को गर्त में स्कैन नहीं करेगा, और सभी सरणी को सॉर्ट नहीं करेगा।

class MyList : IEnumerable<int>
{

    int maxCount = 0;

    public int RequestCount
    {
        get;
        private set;
    }
    public MyList(int maxCount)
    {
        this.maxCount = maxCount;
    }
    public void Reset()
    {
        RequestCount = 0;
    }
    #region IEnumerable<int> Members

    public IEnumerator<int> GetEnumerator()
    {
        int i = 0;
        while (i < maxCount)
        {
            RequestCount++;
            yield return i++;
        }
    }

    #endregion

    #region IEnumerable Members

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        throw new NotImplementedException();
    }

    #endregion
}
class Program
{
    static void Main(string[] args)
    {
        var list = new MyList(15);
        list.Take(5).ToArray();
        Console.WriteLine(list.RequestCount); // 5;

        list.Reset();
        list.OrderBy(q => q).Take(5).ToArray();
        Console.WriteLine(list.RequestCount); // 15;

        list.Reset();
        list.Where(q => (q & 1) == 0).Take(5).ToArray();
        Console.WriteLine(list.RequestCount); // 9; (first 5 odd)

        list.Reset();
        list.Where(q => (q & 1) == 0).Take(5).OrderBy(q => q).ToArray();
        Console.WriteLine(list.RequestCount); // 9; (first 5 odd)
    }
}

25
सिवाय इसके कि अब आप उन्हें चुनने के बाद केवल पहले 5 तत्वों का आदेश दे रहे हैं। यह तेजी से हो सकता है, लेकिन इसके अलग-अलग शब्दार्थ भी हैं, जो वास्तव में लोग जो हासिल करना चाहते हैं, वह होने की संभावना कम है।
ग्रेग बीच
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.