स्विफ्ट में सूची आइटम का सूचकांक कैसे खोजें?


443

मैं एक item indexखोज करके खोजने की कोशिश कर रहा हूं list। किसी को पता है कि कैसे करना है?

मुझे लगता है कि वहाँ है list.StartIndexऔर list.EndIndexमैं अजगर की तरह कुछ करना चाहता हूँ list.index("text")

जवाबों:


823

जैसा कि स्विफ्ट कुछ मायने में ऑब्जेक्ट-ओरिएंटेड से अधिक कार्यात्मक है (और एरर्स स्ट्रक्चर हैं, ऑब्जेक्ट नहीं), सरणी पर संचालित करने के लिए फ़ंक्शन "ढूंढें" का उपयोग करें, जो एक वैकल्पिक मान लौटाता है, इसलिए शून्य मान को संभालने के लिए तैयार रहें:

let arr:Array = ["a","b","c"]
find(arr, "c")!              // 2
find(arr, "d")               // nil

स्विफ्ट 2.0 के लिए अपडेट:

पुराने findफ़ंक्शन को स्विफ्ट 2.0 के साथ और अधिक समर्थित नहीं है!

स्विफ्ट 2.0 के साथ, (जो लागू होता है) के Arrayविस्तार में परिभाषित फ़ंक्शन का उपयोग करके तत्व के सूचकांक को खोजने की क्षमता प्राप्त करता है :CollectionTypeArray

let arr = ["a","b","c"]

let indexOfA = arr.indexOf("a") // 0
let indexOfB = arr.indexOf("b") // 1
let indexOfD = arr.indexOf("d") // nil

इसके अतिरिक्त, एक विधेय को पूरा करने वाले एक सरणी में पहला तत्व ढूंढना एक अन्य एक्सटेंशन द्वारा समर्थित है CollectionType:

let arr2 = [1,2,3,4,5,6,7,8,9,10]
let indexOfFirstGreaterThanFive = arr2.indexOf({$0 > 5}) // 5
let indexOfFirstGreaterThanOneHundred = arr2.indexOf({$0 > 100}) // nil

ध्यान दें कि ये दोनों फ़ंक्शन वैकल्पिक मान लौटाते हैं, जैसा findकि पहले था।

स्विफ्ट 3.0 के लिए अपडेट:

ध्यान दें कि indexOf का सिंटैक्स बदल गया है। Equatableआपके अनुरूप आइटम के लिए उपयोग कर सकते हैं:

let indexOfA = arr.index(of: "a")

विधि का एक विस्तृत दस्तावेज https://developer.apple.com/reference/swift/array/1689674.index पर पाया जा सकता है

उन सरणी वस्तुओं के लिए, जिनका Equatableआपको उपयोग करने की आवश्यकता नहीं है index(where:):

let index = cells.index(where: { (item) -> Bool in
  item.foo == 42 // test if this is the item you're looking for
})

स्विफ्ट 4.2 के लिए अपडेट:

स्विफ्ट 4.2 के साथ, indexअब नहीं किया जाता है, लेकिन में अलग किया जाता firstIndexऔर lastIndexबेहतर स्पष्टीकरण के लिए। तो इस बात पर निर्भर करता है कि आप आइटम के पहले या अंतिम इंडेक्स की तलाश कर रहे हैं:

let arr = ["a","b","c","a"]

let indexOfA = arr.firstIndex(of: "a") // 0
let indexOfB = arr.lastIndex(of: "a") // 3

22
आपने खोज फ़ंक्शन के बारे में कहां सीखा? मैं "खोज" या किसी भी अन्य वैश्विक कार्यों के किसी भी दस्तावेज को खोजने के लिए प्रतीत नहीं कर सकता
जोहान्स

14
ओओपी दुनिया से आ रहा है, मुझे इस तरह के मुफ्त फ़्लोटिंग कार्यों को कैसे करना चाहिए?
रुडोल्फ एडमकोविच

4
वे बड़े पैमाने पर अनिर्दिष्ट प्रतीत होते हैं। व्यावहारिक सूची देखें ।/2014/06/14/… एक सूची के लिए (लेकिन ध्यान रखें कि मैंने जाँच नहीं की है कि सूची पूरी है या अद्यतित है)।
सेबेस्टियन शूथ

5
जोहान्स और @ रुडोल्फ - डैश.एप्प का उपयोग करते हैं। यह ब्राउज़िंग दस्तावेज के लिए OS X ऐप है। इसमें स्विफ्ट के लिए एक भाषा संदर्भ है जिसमें सभी नि: शुल्क फ्लोटिंग कार्यों की एक सूची है। फ़िल्टर करना और खोजना आसान है। इसके बिना नहीं रह सकते।
ब्योर्न

4
FYI करें: यदि आप indexOfअपने द्वारा परिभाषित संरचनाओं के एक सरणी पर उपयोग कर रहे हैं , तो आपकी संरचना को Equatableप्रोटोकॉल का पालन करना होगा ।
मैथ्यू क्विरोस

202

tl; डॉ:

कक्षाओं के लिए, आप देख सकते हैं:

let index = someArray.firstIndex{$0 === someObject}

पूर्ण उत्तर:

मुझे लगता है कि यह उल्लेख के लायक है कि संदर्भ प्रकारों के साथ ( class) आप एक पहचान की तुलना करना चाहते हैं , जिस स्थिति में आपको ===पहचानकर्ता को विधेय बंद करने में उपयोग करने की आवश्यकता है :


स्विफ्ट 5, स्विफ्ट 4.2:

let person1 = Person(name: "John")
let person2 = Person(name: "Sue")
let person3 = Person(name: "Maria")
let person4 = Person(name: "Loner")

let people = [person1, person2, person3]

let indexOfPerson1 = people.firstIndex{$0 === person1} // 0
let indexOfPerson2 = people.firstIndex{$0 === person2} // 1
let indexOfPerson3 = people.firstIndex{$0 === person3} // 2
let indexOfPerson4 = people.firstIndex{$0 === person4} // nil

ध्यान दें कि उपरोक्त सिंटैक्स अनुगामी क्लोज़र सिंटैक्स का उपयोग करता है, और इसके बराबर है:

let indexOfPerson1 = people.firstIndex(where: {$0 === person1})


स्विफ्ट 4 / स्विफ्ट 3 - फ़ंक्शन को कहा जाता था index

स्विफ्ट 2 - फ़ंक्शन को कहा जाता था indexOf

* लागू करने वाले प्रकारों के बारे में पॉलबेली द्वारा प्रासंगिक और उपयोगी टिप्पणी पर ध्यान दें , जहां आपको यह विचार करने की आवश्यकता है कि क्या आपको ( पहचान ऑपरेटर) या ( समानता ऑपरेटर) का उपयोग करने की तुलना करनी चाहिए । यदि आप मिलान का उपयोग करने का निर्णय लेते हैं , तो आप बस दूसरों द्वारा सुझाई गई विधि का उपयोग कर सकते हैं ( )।classEquatable=======people.firstIndex(of: person1)


6
यह सोच रहे लोगों के लिए एक उपयोगी पोस्ट है .indexOf (x) काम नहीं करता है - यह समाधान पूर्वव्यापी में अप्रत्याशित लेकिन पूरी तरह से स्पष्ट है।
मॉरी मार्कोविट्ज़

1
इसके लिए बहुत बहुत धन्यवाद, लेकिन यह मेरे लिए बिल्कुल स्पष्ट नहीं है। मैंने प्रलेखन को देखा और मुझे वास्तव में समझ में नहीं आया कि एक संदर्भ प्रकार पर indexOf का उपयोग करते समय मुझे एक विधेय बंद करने की आवश्यकता क्यों होगी? ऐसा लगता है कि indexOf को पहले से ही संदर्भ प्रकारों को संभालने में सक्षम होना चाहिए। यह जानना चाहिए कि यह एक संदर्भ प्रकार है और मूल्य प्रकार नहीं है।
क्रिस

7
यदि प्रोटोकॉल Personलागू किया जाता Equatableहै, तो इसकी आवश्यकता नहीं होगी।
पॉलबेली

2
मैं प्राप्त कर रहा हूँ: Binary operator '===' cannot be applied to operands of type '_' and 'Post', Postमेरे struct है ... किसी भी विचार?
डेविड ने

@DavidSeek, structs(और enums) मान प्रकार हैं, संदर्भ प्रकार नहीं। केवल संदर्भ प्रकार (जैसे class) में पहचान तुलना तर्क ( ===) है। क्या करना है इसके लिए अन्य उत्तरों की जांच करें structs(मूल रूप से आप बस इसका उपयोग करते हैं array.index(of: myStruct), सुनिश्चित करें कि किस प्रकार के myStructअनुरूप Equatable( ==))।
निकोले सुवाँझावी

81

आप filterकिसी सरणी को बंद कर सकते हैं :

var myList = [1, 2, 3, 4]
var filtered = myList.filter { $0 == 3 }  // <= returns [3]

और आप एक सरणी गिन सकते हैं:

filtered.count // <= returns 1

तो आप यह निर्धारित कर सकते हैं कि क्या एक सरणी में इनको मिलाकर आपका तत्व शामिल है:

myList.filter { $0 == 3 }.count > 0  // <= returns true if the array includes 3

यदि आप स्थिति ढूंढना चाहते हैं, तो मुझे फैंसी रास्ता नहीं दिखता है, लेकिन आप निश्चित रूप से इसे इस तरह कर सकते हैं:

var found: Int?  // <= will hold the index if it was found, or else will be nil
for i in (0..x.count) {
    if x[i] == 3 {
        found = i
    }
}

संपादित करें

जब हम इस पर हैं, एक मजेदार अभ्यास के लिए Arrayएक findविधि है:

extension Array {
    func find(includedElement: T -> Bool) -> Int? {
        for (idx, element) in enumerate(self) {
            if includedElement(element) {
                return idx
            }
        }
        return nil
    }
}

अब हम यह कर सकते हैं:

myList.find { $0 == 3 }
// returns the index position of 3 or nil if not found

मौज-मस्ती के लिए मैंने एक और उदाहरण जोड़ा जहां मैं बिलिन का विस्तार Arrayएक ऐसी findविधि करता हूं जो आपको चाहिए। मैं अभी तक नहीं जानता कि क्या यह एक अच्छा अभ्यास है, लेकिन यह एक स्वच्छ प्रयोग है।
gwcoffey

2
बस यह इंगित करना चाहते हैं, कि आपको डॉक्स के अनुसार ++ आईडीएक्स का उपयोग करना चाहिए: "जब तक आपको i ++ के विशिष्ट व्यवहार की आवश्यकता नहीं होती है, यह अनुशंसा की जाती है कि आप सभी मामलों में ++ i और --i का उपयोग करें, क्योंकि उनके पास विशिष्ट अपेक्षित है i को संशोधित करने और परिणाम वापस करने का व्यवहार। "
लोगन

अच्छा निर्णय। जैसा कि आप इसे पोस्ट कर रहे थे मैं इसे संशोधित करने के लिए उपयोग कर रहा था enumerateताकि यह अब लागू न हो, लेकिन आप बिल्कुल सही हैं।
gwcoffey

हाँ, मुझे याद था कि जब मैं गुज़र रहा था तो एक उदाहरण में इसे देखा था। अब आदत में खुद को स्थापित करने की कोशिश की जा रही है :)
लोगन

4
इसके लिए स्विफ्ट 2 / एक्सकोड 7 के तहत काम करने के लिए आपको इसे निम्नानुसार संशोधित करना होगा। बदलें (शामिल हैं: टी -> बूल) के साथ (शामिल: एलिमेंट: एलिमेंट -> बूल) और एन्यूमरेट (स्व) को स्वयं में बदलें।
स्कूटर

35

स्विफ्ट 5

func firstIndex(of element: Element) -> Int?

var alphabets = ["A", "B", "E", "D"]

उदाहरण 1

let index = alphabets.firstIndex(where: {$0 == "A"})

example2

if let i = alphabets.firstIndex(of: "E") {
    alphabets[i] = "C" // i is the index
}
print(alphabets)
// Prints "["A", "B", "C", "D"]"

25

जबकि indexOf()पूरी तरह से काम करता है, यह केवल एक सूचकांक देता है।

मैं उन तत्वों के लिए अनुक्रमित की एक सरणी प्राप्त करने के लिए एक सुरुचिपूर्ण तरीके की तलाश कर रहा था जो कुछ स्थिति को संतुष्ट करते हैं।

यहां बताया गया है कि यह कैसे किया जा सकता है:

स्विफ्ट 3:

let array = ["apple", "dog", "log"]

let indexes = array.enumerated().filter {
    $0.element.contains("og")
    }.map{$0.offset}

print(indexes)

स्विफ्ट 2:

let array = ["apple", "dog", "log"]

let indexes = array.enumerate().filter {
    $0.element.containsString("og")
    }.map{$0.index}

print(indexes)

12

कस्टम क्लास के लिए, आपको इक्विटेबल प्रोटोकॉल लागू करना होगा।

import Foundation

func ==(l: MyClass, r: MyClass) -> Bool {
  return l.id == r.id
}

class MyClass: Equtable {
    init(id: String) {
        self.msgID = id
    }

    let msgID: String
}

let item = MyClass(3)
let itemList = [MyClass(1), MyClass(2), item]
let idx = itemList.indexOf(item)

printl(idx)

9

स्विफ्ट 2 के लिए अपडेट:

अनुक्रम.कंटेंस (तत्व) : यदि दिए गए अनुक्रम (जैसे कि एक सरणी) में निर्दिष्ट तत्व है तो सही है।

स्विफ्ट 1:

यदि आप यह देखना चाहते हैं कि कोई तत्व किसी सरणी के अंदर समाहित है या नहीं, तो बस एक बूलियन संकेतक प्राप्त करें, contains(sequence, element)इसके बजाय उपयोग करें find(array, element):

समाहित है (अनुक्रम, तत्व) : यदि दिया गया अनुक्रम (जैसे कि एक सरणी) में निर्दिष्ट तत्व है तो सही है।

नीचे उदाहरण देखें:

var languages = ["Swift", "Objective-C"]
contains(languages, "Swift") == true
contains(languages, "Java") == false
contains([29, 85, 42, 96, 75], 42) == true
if (contains(languages, "Swift")) {
  // Use contains in these cases, instead of find.   
}


6

स्विफ्ट 4. यदि आपके एरे में टाइप के तत्व हैं [स्ट्रिंग: एनीऑब्जेक्ट]। इसलिए तत्व के सूचकांक को खोजने के लिए नीचे दिए गए कोड का उपयोग करें

var array = [[String: AnyObject]]()// Save your data in array
let objectAtZero = array[0] // get first object
let index = (self.array as NSArray).index(of: objectAtZero)

या यदि आप शब्दकोश से कुंजी के आधार पर सूचकांक प्राप्त करना चाहते हैं। यहाँ सरणी में मॉडल वर्ग की वस्तुएँ हैं और मैं आईडी गुण मिलान कर रहा हूँ।

   let userId = 20
    if let index = array.index(where: { (dict) -> Bool in
           return dict.id == userId // Will found index of matched id
    }) {
    print("Index found")
    }
OR
      let storeId = Int(surveyCurrent.store_id) // Accessing model key value
      indexArrUpTo = self.arrEarnUpTo.index { Int($0.store_id) == storeId }! // Array contains models and finding specific one

4

स्विफ्ट 2.1

var array = ["0","1","2","3"]

if let index = array.indexOf("1") {
   array.removeAtIndex(index)
}

print(array) // ["0","2","3"]

स्विफ्ट 3

var array = ["0","1","2","3"]

if let index = array.index(of: "1") {
    array.remove(at: index)
}
array.remove(at: 1)

3
आप एक उत्परिवर्तन कर रहे हैं let array? का उपयोग selfसंदिग्ध है।
च्यो

4

में स्विफ्ट 4 , यदि आप अपने डेटामॉडल सरणी के माध्यम से traversing कर रहे हैं, Equatable प्रोटोकॉल के लिए सुनिश्चित करें कि आपके डेटा मॉडल अनुरूप, एलएचएस लागू विधि आरएचएस बनाने के =, और उसके बाद ही आप ".index (की" का उपयोग कर सकते हैं। उदाहरण के लिए

class Photo : Equatable{
    var imageURL: URL?
    init(imageURL: URL){
        self.imageURL = imageURL
    }

    static func == (lhs: Photo, rhs: Photo) -> Bool{
        return lhs.imageURL == rhs.imageURL
    }
}

और तब,

let index = self.photos.index(of: aPhoto)

4

स्विफ्ट 2 में (Xcode 7 के साथ), प्रोटोकॉल द्वारा प्रदान की गई विधि Arrayशामिल है। (वास्तव में, दो विधियाँ-एक जो तर्क का मिलान करने के लिए समानता का उपयोग करती है, और दूसरी जो एक बंद का उपयोग करती है।)indexOfCollectionTypeindexOf

स्विफ्ट 2 से पहले, सामान्य प्रकार के संग्रह के लिए कोई रास्ता नहीं था जैसे कि उन्हें (जैसे सरणियों) से प्राप्त कंक्रीट प्रकार के लिए तरीके प्रदान करना। इसलिए, स्विफ्ट 1.x में, "इंडेक्स ऑफ़" एक वैश्विक फ़ंक्शन है ... और इसका नाम बदल दिया गया, इसलिए, स्विफ़्ट 1.x में, उस वैश्विक फ़ंक्शन को कहा जाता हैfind

यह भी का उपयोग करना संभव है (न कि आवश्यक) है indexOfObjectसे विधि NSArray... या अन्य, अधिक परिष्कृत खोज मेथ फाउंडेशन की ओर से स्विफ्ट मानक पुस्तकालय में समकक्ष नहीं है कि जिले के किसी भी। बस import Foundation(या एक अन्य मॉड्यूल जो कि ट्रांमिटिवली फाउंडेशन का आयात करता है), आपके Arrayको कास्ट करता है NSArray, और आप कई खोज विधियों का उपयोग कर सकते हैं NSArray


4

इस समाधान का कोई भी मेरे लिए काम करता है

यह समाधान मैं स्विफ्ट 4 के लिए है:

let monday = Day(name: "M")
let tuesday = Day(name: "T")
let friday = Day(name: "F")

let days = [monday, tuesday, friday]

let index = days.index(where: { 
            //important to test with === to be sure it's the same object reference
            $0 === tuesday
        })


2

यदि आप अभी भी स्विफ्ट 1.x में काम कर रहे हैं

फिर कोशिश करो,

let testArray = ["A","B","C"]

let indexOfA = find(testArray, "A") 
let indexOfB = find(testArray, "B")
let indexOfC = find(testArray, "C")

1

SWIFT 3 के लिए आप एक साधारण फ़ंक्शन का उपयोग कर सकते हैं

func find(objecToFind: String?) -> Int? {
   for i in 0...arrayName.count {
      if arrayName[i] == objectToFind {
         return i
      }
   }
return nil
}

यह नंबर की स्थिति देगा, इसलिए आप इसका उपयोग कर सकते हैं

arrayName.remove(at: (find(objecToFind))!)

उपयोगी होने की उम्मीद है


1

स्विफ्ट 4

मान लीजिए कि आप कार्डबटन में कार्डबटन नामक सरणी से एक नंबर स्टोर करना चाहते हैं, आप इसे इस तरह से कर सकते हैं:

let cardNumber = cardButtons.index(of: sender)

प्रेषक आपके बटन का नाम है


0

स्विफ्ट 4

संदर्भ प्रकारों के लिए:

extension Array where Array.Element: AnyObject {

    func index(ofElement element: Element) -> Int? {
        for (currentIndex, currentElement) in self.enumerated() {
            if currentElement === element {
                return currentIndex
            }
        }
        return nil
    }
}

0

स्विफ्ट 4/5 में, इंडेक्स खोजने के लिए "फर्स्टइंडेक्स" का उपयोग करें।

let index = array.firstIndex{$0 == value}

0

मामले में किसी को यह समस्या है

Cannot invoke initializer for type 'Int' with an argument list of type '(Array<Element>.Index?)'

jsut ऐसा करते हैं

extension Int {
    var toInt: Int {
        return self
    }
}

फिर

guard let finalIndex = index?.toInt else {
    return false
}

0

के लिये (>= swift 4.0)

यह बहुत सरल है। निम्नलिखित Arrayवस्तु पर विचार करें ।

var names: [String] = ["jack", "rose", "jill"]

तत्व का सूचकांक प्राप्त करने के लिए rose, आपको बस इतना करना है:

names.index(of: "rose") // returns 1

ध्यान दें:

  • Array.index(of:)एक रिटर्न Optional<Int>

  • nil तात्पर्य है कि तत्व सरणी में मौजूद नहीं है।

  • आप दिए गए मान को लागू करने या if-letवैकल्पिक के आसपास पाने के लिए उपयोग करना चाहते हैं।


0

बस FirstIndex विधि का उपयोग करें।

array.firstIndex(where: { $0 == searchedItem })
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.