किसी एकल चरण में सूची में किसी आइटम का सूचकांक कैसे प्राप्त करें?


193

मैं किसी सूची में किसी वस्तु के सूचकांक को कैसे पा सकता हूं, उसके माध्यम से जाने बिना?

वर्तमान में यह बहुत अच्छा नहीं लगता है - सूची के माध्यम से एक ही आइटम के लिए दो बार खोज करना, बस सूचकांक प्राप्त करने के लिए:

var oProp = something;

int theThingIActuallyAmInterestedIn = myList.IndexOf(myList.Single(i => i.Prop == oProp));

जवाबों:


435

कैसे के बारे में List.FindIndex विधि :

int index = myList.FindIndex(a => a.Prop == oProp);

यह विधि एक रैखिक खोज करती है; इसलिए, यह विधि O (n) ऑपरेशन है, जहाँ n की गणना है।

यदि आइटम नहीं मिला है, तो यह -1 वापस आ जाएगा


2
कैसे के बारे में int index?
डायलन सेन्स्की

2
@DylanChensky वह JS को बहुत अधिक कोडित कर रहा है
lenny

9
संदर्भ के लिए, यदि आइटम नहीं मिला है; यह -1 लौट आएगा
डैनियल फिलीप


71

संपादित करें: यदि आप केवल एक का उपयोग कर रहे हैं List<>और आपको केवल सूचकांक की आवश्यकता है, तो List.FindIndexवास्तव में सबसे अच्छा तरीका है। मैं इस उत्तर को उन लोगों के लिए छोड़ दूंगा, जिन्हें कुछ अलग करने की जरूरत है (जैसे किसी के ऊपर IEnumerable<>)।

ओवरलोड का उपयोग करें Selectजो एक इंडेक्स को विधेय में लेता है, इसलिए आप अपनी सूची को एक (इंडेक्स, वैल्यू) जोड़ी में बदलते हैं:

var pair = myList.Select((Value, Index) => new { Value, Index })
                 .Single(p => p.Value.Prop == oProp);

फिर:

Console.WriteLine("Index:{0}; Value: {1}", pair.Index, pair.Value);

या यदि आप केवल इंडेक्स चाहते हैं और आप इसे कई स्थानों पर उपयोग कर रहे हैं, तो आप आसानी से अपनी खुद की एक्सटेंशन विधि लिख सकते हैं, जो की तरह थी Where, लेकिन मूल वस्तुओं को वापस करने के बजाय, यह उन वस्तुओं के इंडेक्स को लौटाता है जो विधेय से मेल खाते थे।


ऐसा लगता है कि वह जो चाहता है वह सूचकांक है। सूची <>। FindIndex (Predicate <>) सबसे अच्छा तरीका है। हालांकि प्रश्न शीर्षक अन्यथा अलग हो जाएगा, लेकिन ओपी का वर्णन स्पष्ट है कि उसे केवल "int theThingIActuallyAmInterestedIn" सूचकांक की आवश्यकता है
लुईस

1
@LastCoder: अहा - फाइंडइंडेक्स छूट गया था। हां, मैं पूरी तरह से सहमत हूं।
जॉन स्कीट

बस स्पष्ट होने के लिए, "सूचकांक / मूल्य -> ​​एकल" दृष्टिकोण "बेहतर" है (यहां बिग-ओ के संदर्भ में तेजी से मतलब है) मैन्युअल रूप से दो बार पुनरावृत्ति करने की तुलना में? या LINQ2Objects प्रदाता एक पुनरावृत्तियों को दूर करने के लिए पर्याप्त स्मार्ट है? (मैं यह धारणा बना रहा हूं कि सिलेक्ट और सिंगल दोनों आम तौर पर बोल रहे हैं ओ (एन) ऑपरेशंस) हैं
सारा

1
@kai: मुझे लगता है कि आपको मूल रूप से LINQ कैसे काम करता है, इस पर आपको पढ़ने की जरूरत है। किसी टिप्पणी में विस्तार से व्याख्या करना बहुत जटिल है। हालाँकि ... यह केवल एक बार स्रोत संग्रह पर पुनरावृत्ति कर रहा है। LINQ एक पाइपलाइन सेट करता है, जो आलसी रूप से इनपुट अनुक्रम को दूसरे अनुक्रम में बदल देता है, और फिर Single()ऑपरेशन उस अनुक्रम पर पुनरावृत्त होता है और एकल आइटम को ढूंढता है जो कि विधेय से मेल खाता है। अधिक जानकारी के लिए, मेरी edulinq ब्लॉग श्रृंखला पढ़ें: codeblog.jonskeet.uk/category/edulinq
जॉन स्कीट

1
+1 मुझे इस समाधान की आवश्यकता थी। बॉस ने सोचा कि मैं एक बार के लिए स्मार्ट था। मुझे इसे सावधानीपूर्वक दस्तावेज़ करने की सलाह दी गई थी, क्योंकि यह एक अनाम प्रकार का उपयोग करता था और क्षेत्र में अगले कोडर के लिए स्पष्ट नहीं हो सकता है।
एडम वेल्स

14

यदि आप LINQ का उपयोग नहीं करना चाहते हैं, तो:

int index;
for (int i = 0; i < myList.Count; i++)
{
    if (myList[i].Prop == oProp)
    {
       index = i;
       break;
    }
}

इस तरह आप केवल एक बार सूची की पुनरावृत्ति कर रहे हैं।


22
@KingKing किसी ने कहा कि यह है।
तोमर डब्ल्यू

1
क्या यह उसी तरह का कार्यान्वयन है जैसा कि लिनक FindIndexने ब्याज से बाहर किया था?
Coops

2
शायद एक ही कोड नहीं, सूची में कुछ साफ-सुथरे अनुकूलन हैं। लेकिन मुझे यह विश्वास करना मुश्किल है कि वे ओ (एन) से कम में एक अनियंत्रित सूची खोज सकते हैं, इसलिए मैं कहूंगा कि वे वास्तव में अभ्यास में समान हैं।
सारा

6
  1. सूची में किसी भी स्ट्रिंग मान के लिए सूचकांक खोजने का सरल उपाय।

स्ट्रिंग की सूची के लिए यहाँ कोड है:

int indexOfValue = myList.FindIndex(a => a.Contains("insert value from list"));
  1. सूची में किसी भी पूर्णांक मूल्य के लिए सूचकांक खोजने के लिए सरल समाधान।

यहाँ कोड ऑफ इंटेगर की सूची है:

    int indexOfNumber = myList.IndexOf(/*insert number from list*/);

2

यहाँ IEnumerable के लिए एक कॉपी / पेस्ट-सक्षम एक्सटेंशन विधि है

public static class EnumerableExtensions
{
    /// <summary>
    /// Searches for an element that matches the conditions defined by the specified predicate,
    /// and returns the zero-based index of the first occurrence within the entire <see cref="IEnumerable{T}"/>.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="list">The list.</param>
    /// <param name="predicate">The predicate.</param>
    /// <returns>
    /// The zero-based index of the first occurrence of an element that matches the conditions defined by <paramref name="predicate"/>, if found; otherwise it'll throw.
    /// </returns>
    public static int FindIndex<T>(this IEnumerable<T> list, Func<T, bool> predicate)
    {
        var idx = list.Select((value, index) => new {value, index}).Where(x => predicate(x.value)).Select(x => x.index).First();
        return idx;
    }
}

का आनंद लें।


2

अगर किसी को Arrayसंस्करण के लिए आश्चर्य होता है , तो यह इस तरह से होता है:

int i = Array.FindIndex(yourArray, x => x == itemYouWant);
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.