मैं सूची में अंतिम तत्व कैसे पा सकता हूं <>?


172

निम्नलिखित मेरे कोड से एक उद्धरण है:

public class AllIntegerIDs 
{
    public AllIntegerIDs() 
    {            
        m_MessageID = 0;
        m_MessageType = 0;
        m_ClassID = 0;
        m_CategoryID = 0;
        m_MessageText = null;
    }

    ~AllIntegerIDs()
    {
    }

    public void SetIntegerValues (int messageID, int messagetype,
        int classID, int categoryID)
    {
        this.m_MessageID = messageID;
        this.m_MessageType = messagetype;
        this.m_ClassID = classID;
        this.m_CategoryID = categoryID;
    }

    public string m_MessageText;
    public int m_MessageID;
    public int m_MessageType;
    public int m_ClassID;
    public int m_CategoryID;
}

मैं अपने मुख्य () फ़ंक्शन कोड में निम्नलिखित का उपयोग करने की कोशिश कर रहा हूं:

List<AllIntegerIDs> integerList = new List<AllIntegerIDs>();

/* some code here that is ised for following assignments*/
{
   integerList.Add(new AllIntegerIDs());
   index++;
   integerList[index].m_MessageID = (int)IntegerIDsSubstring[IntOffset];
   integerList[index].m_MessageType = (int)IntegerIDsSubstring[IntOffset + 1];
   integerList[index].m_ClassID = (int)IntegerIDsSubstring[IntOffset + 2];
   integerList[index].m_CategoryID = (int)IntegerIDsSubstring[IntOffset + 3];
   integerList[index].m_MessageText = MessageTextSubstring;
}

समस्या यहाँ है: मैं अपनी सूची में सभी तत्वों को एक लूप का उपयोग करके प्रिंट करने की कोशिश कर रहा हूं:

for (int cnt3 = 0 ; cnt3 <= integerList.FindLastIndex ; cnt3++) //<----PROBLEM HERE
{
   Console.WriteLine("{0}\t{1}\t{2}\t{3}\t{4}\n", integerList[cnt3].m_MessageID,integerList[cnt3].m_MessageType,integerList[cnt3].m_ClassID,integerList[cnt3].m_CategoryID, integerList[cnt3].m_MessageText);
}

मैं अंतिम तत्व ढूंढना चाहता हूं ताकि मैं लूप के लिए अपने में cnt3 को समान करूं और सूची में सभी प्रविष्टियों को प्रिंट कर सकूं। सूची में प्रत्येक तत्व वर्ग AllIntegerIDs का एक ऑब्जेक्ट है जैसा कि कोड नमूने में ऊपर बताया गया है। मुझे सूची में अंतिम वैध प्रविष्टि कैसे मिलेगी?

क्या मुझे integerList की तरह कुछ का उपयोग करना चाहिए।

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

धन्यवाद, वीरेन


@ वीरेन: मैंने इसे ठीक से दिखाने के लिए कोड का उपयोग किया। यदि आपने मेरे अधीन संपादन किया है तो क्या आप यह सुनिश्चित कर सकते हैं कि मैंने उन्हें पूर्ववत नहीं किया?
सैम हैरवेल

8
आपके प्रश्न से संबंधित नहीं है, लेकिन आपको वास्तव में अंतिम रूप से लागू नहीं करना चाहिए जब तक कि इसकी आवश्यकता न हो।
ब्रायन रासमुसेन

प्रश्न से संबंधित नहीं है, लेकिन पठनीयता और स्थिरता के लिए, मैं आपको सुझाव देता हूं कि AllIntegerIDs newItem = new AllIntegerID();, सभी क्षेत्रों को निर्दिष्ट करने के लिए उपयोग करें और फिर कॉल करें integerList.Add(newItem)। या खेतों के बजाय गुणों का उपयोग करें और C # 3.0 ऑब्जेक्ट इनिशियल सिंटैक्स का उपयोग करें।
थोरिन 20

जवाबों:


208

यदि आप केवल उस सूची में अंतिम आइटम का उपयोग करना चाहते हैं जो आप कर सकते हैं

if(integerList.Count>0)
{
   var item = integerList[integerList.Count - 1];
}

सूची में आइटमों की कुल संख्या प्राप्त करने के लिए आप गणना संपत्ति का उपयोग कर सकते हैं

var itemCount = integerList.Count;

17
@ जारेड मुझे लगता है कि आप इस पंक्ति को जोड़ना भूल गए हैं "अगर (पूर्णांक सूची। क्राउंट! = 0)" पहली पंक्ति से पहले
प्रभाकरन

21
IMHO यह शीर्ष उत्तर के लायक नहीं है, यह बहुत पढ़ता है और गिनती शून्य होने पर एक त्रुटि के लिए मौका छोड़ देता है। CleanCode ™ दृष्टिकोण का उपयोग किया जाएगा Last/ LastOrDefaultनीचे वर्णित के रूप में।
चिल्लीटॉम

2
जैसा कि पहले बताया गया है, यह उत्तर उस स्थिति को ध्यान में नहीं रखता है जब सूची खाली है और इसका उपयोग IMHO नहीं किया जाना चाहिए।
मेर्र

2
@chillitom @merrr LINQ एक्सटेंशन विधियों का उपयोग करने से मदद नहीं मिलती है। Enumerable.Lastयदि सूची खाली है तो अपवाद छोड़ देंगे। यदि आप कॉल करते हैं Enumerable.LastOrDefaultऔर मूल्य की सूची पास करते हैं तो सूची खाली होने पर डिफ़ॉल्ट मान वापस कर दिया जाएगा। इसलिए यदि आप 0 से वापस आते हैं, तो आपको List<int>पता नहीं चलेगा कि सूची खाली थी या अंतिम मान 0. था। संक्षेप में, आपको Countउस पुनर्प्राप्ति तंत्र की जांच करने की आवश्यकता है जिसे आप उपयोग करने का निर्णय लेते हैं।
0b101010

4
@chillitom प्रत्येक अपने स्वयं के। ऐसे उदाहरणों में जहां आप जानते हैं कि एक सूची आबाद है, मुझे लगता var element = list[list.Count - 1]है कि बहुत ही रसीला और पठनीय है। विस्तार विधियों को लागू करने की आवश्यकता नहीं है
0b101010

276

किसी संग्रह के अंतिम आइटम को प्राप्त करने के लिए LastOrDefault () और Last () एक्सटेंशन विधियों का उपयोग करें

var lastItem = integerList.LastOrDefault();

या

var lastItem = integerList.Last();

जोड़ने के लिए रिमाइबर using System.Linq;, या यह विधि उपलब्ध नहीं होगी।


17
हां यह सबसे अच्छा तरीका है, लास्ट और लास्ट
ऑर्डीफॉल्ट

2
@Gusdor मैंने इसे प्रलेखित नहीं देखा है, लेकिन मैं इन चीजों के लिए सीधे स्रोतों की ओर रुख करता हूं (या रेस्चैपर, डॉटपेक या ILSpy जैसे डिस्सेम्बलर का उपयोग करता हूं)। से वहाँ मुझे लगता है कि देख सकते हैं First, FirstOrDefault, Last, LastOrDefault, Single, SingleOrDefault, ElementAtऔर ElementAtOrDefaultके लिए अनुकूलित कर रहे हैं IList<TSource>, Countऔर Containsके लिए अनुकूलित कर रहे हैं ICollection<TSource>और Cast<TResult>के लिए अनुकूलित है IEnumerable<TResult>
चिल्लीटॉम

8
जोड़ना सुनिश्चित करेंusing System.Linq;
हाइब्रिड

4
@chillitom द्वारा उजागर की गई विस्तार विधियाँ System.Linq.Enumerableवास्तव में 'अनुकूलित' नहीं हैं। यहाँ Enumerable.Lastविधि के लिए कोड है ।
0b101010

4
@chillitom के स्रोत को पढ़ने के बाद System.Linq.Enumerable.Last, मैं 0b101010 से सहमत हूं - Last()कोड " s के लिए अनुकूलित" नहीं हैList<> - Last()सिर्फ एक बदसूरत आवरण है, जो return list[list.Count-1]तर्क के मामले में चूक है IList, और मामले में अंत तक सूची पर पुनरावृत्ति करता है यह नहीं है ... अगर यह एक बहुत खराब समाधान है, तो यह IListहै LinkedList, क्योंकि अनुक्रमणिका पूरी सूची के माध्यम से अनावश्यक रूप से जाएगी (मुझे Item[]इंडेक्स के साथ पीछे की ओर घूमते हुए एक ओवरराइड नहीं मिला है। C # स्रोतों में गणना / 2, YMMV )

20

आओ हम एक सूची के अंतिम तत्व को सुरक्षित रूप से संबोधित करें

यह मानते हुए

List<string> myList = new List<string>();

फिर

//NOT safe on an empty list!
string myString = myList[myList.Count -1];

//equivalent to the above line when Count is 0, bad index
string otherString = myList[-1];

"गिनती -1" एक बुरी आदत है जब तक आप पहले गारंटी नहीं देते कि सूची खाली नहीं है।

खाली सूची के लिए जाँच करने के लिए इसके अलावा कोई सुविधाजनक तरीका नहीं है।

सबसे छोटा तरीका मैं सोच सकता हूं

string myString = (myList.Count != 0) ? myList [ myList.Count-1 ] : "";

आप सभी बाहर जा सकते हैं और एक प्रतिनिधि बना सकते हैं जो हमेशा सच लौटाता है, और इसे फाइंडलास्ट में पास करें, जो अंतिम मान लौटाएगा (या यदि सूची खाली है तो डिफ़ॉल्ट रूप से निर्मित वलय)। यह फ़ंक्शन सूची के अंत में शुरू होता है इसलिए बिग O (1) या निरंतर समय होगा, विधि सामान्य रूप से O (n) होने के बावजूद।

//somewhere in your codebase, a strange delegate is defined
private static bool alwaysTrue(string in)
{
    return true;
}

//Wherever you are working with the list
string myString = myList.FindLast(alwaysTrue);

यदि आप प्रतिनिधि भाग की गणना करते हैं, तो FindLast विधि बदसूरत है, लेकिन इसे केवल एक स्थान घोषित करने की आवश्यकता है। यदि सूची खाली है, तो यह स्ट्रिंग के लिए सूची प्रकार "" का एक डिफ़ॉल्ट निर्मित मान लौटाएगा। हमेशा की तरह प्रतिनिधि को एक कदम आगे ले जाना, इसे स्ट्रिंग प्रकार के बजाय एक टेम्पलेट बनाना, अधिक उपयोगी होगा।


2
प्रतिनिधि को एक लंबोदर अभिव्यक्ति के साथ प्रतिस्थापित किया जा सकता है: myList.FindLast(_unused_variable_name => true);यह प्रकार की परवाह किए बिना काम करेगा। एक छोटा संस्करण है myList.FindLast(_ => true);, लेकिन मुझे लगता है कि सिर्फ अंडरस्कोर (या किसी अन्य एकल चरित्र पहचानकर्ता) कई बार थोड़ा भ्रमित हो सकता है।
बॉब


5

परिवर्तन

for (int cnt3 = 0 ; cnt3 <= integerList.FindLastIndex ; cnt3++)

सेवा

for (int cnt3 = 0 ; cnt3 < integerList.Count; cnt3++)

foreach अक्सर उपयोग करने के लिए अधिक सुविधाजनक होता है, लेकिन थोड़ा धीमा होता है।
एरिक जे।

अगर काउंट का उपयोग कर रहे हैं ... एक -1 करें या आपको एक इंडेक्स एरर मिलेगा। के लिए (int cnt3 = 0; cnt3 <integerList.Count - 1; cnt3 ++)
रिडलरडेव

4
इसलिए मैं <= से बदल गया हूं। कोड के रूप में सही है :-)
एरिक जे।

@ एरिक: यह धीमी गति से हुआ करता था, लेकिन जेआईटी में हिट करने के लिए यह एक तुच्छ मामला है इसलिए मुझे आश्चर्य होगा कि अगर वे अब तक नहीं हुए हैं। : दुन्नो:
सैम हैरवेल

1
@IPX एरेस: लगता है अभी भी एक मुद्दा हो सकता है, डेटा प्रकार के आधार पर आप पुनरावृत्ति कर रहे हैं: stackoverflow.com/questions/365615/…
एरिक जे।


2

आप इसे सूची में तत्वों की संख्या की पहली गणना करके पा सकते हैं

int count = list.Count();

फिर आप सूची में अंतिम तत्व प्राप्त करने के लिए गिनती - 1 को अनुक्रमित कर सकते हैं

int lastNumber = list[count - 1];

2
कृपया डुप्लिकेट उत्तर पोस्ट न करें।
इयान मर्सर


1

सिर्फ सूची पर गणना संपत्ति का उपयोग क्यों न करें?

for(int cnt3 = 0; cnt3 < integerList.Count; cnt3++)

0

यदि आप अपनी सूची में कई बार स्थानीय चर का संदर्भ लेते हैं, तो अपने मूल प्रश्न से स्वतंत्र, आपको बेहतर प्रदर्शन मिलेगा:

AllIntegerIDs ids = new AllIntegerIDs();
ids.m_MessageID = (int)IntegerIDsSubstring[IntOffset];
ids.m_MessageType = (int)IntegerIDsSubstring[IntOffset + 1];
ids.m_ClassID = (int)IntegerIDsSubstring[IntOffset + 2];
ids.m_CategoryID = (int)IntegerIDsSubstring[IntOffset + 3];
ids.m_MessageText = MessageTextSubstring;
integerList.Add(ids);

और आपके forपाश में:

for (int cnt3 = 0 ; cnt3 < integerList.Count ; cnt3++) //<----PROBLEM HERE
{
   AllIntegerIDs ids = integerList[cnt3];
   Console.WriteLine("{0}\t{1}\t{2}\t{3}\t{4}\n",
      ids.m_MessageID,ids.m_MessageType,ids.m_ClassID,ids.m_CategoryID, ids.m_MessageText);
}

-1

मुझे सहमत होना होगा कि एक फॉर्च्यूनर बहुत कुछ आसान होगा

foreach(AllIntegerIDs allIntegerIDs in integerList)
{
Console.WriteLine("{0}\t{1}\t{2}\t{3}\t{4}\n", allIntegerIDs.m_MessageID,
allIntegerIDs.m_MessageType,
allIntegerIDs.m_ClassID,
allIntegerIDs.m_CategoryID,
allIntegerIDs.m_MessageText);
}

इसके अलावा, मैं आपको सार्वजनिक क्षेत्रों के बजाय अपनी जानकारी तक पहुँचने के लिए गुण जोड़ने का सुझाव दूंगा, आपके .net संस्करण के आधार पर आप इसे जोड़ सकते हैं public int MessageType {get; set;}और m_अपने सार्वजनिक क्षेत्रों, संपत्तियों आदि से छुटकारा पा सकते हैं क्योंकि यह वहाँ नहीं होना चाहिए।


हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.