16 ответов:
поскольку swift в некоторых отношениях более функциональна, чем объектно-ориентированная (а массивы-это структуры, а не объекты), используйте функцию "find" для работы с массивом, которая возвращает необязательное значение, поэтому будьте готовы обрабатывать нулевое значение:
let arr:Array = ["a","b","c"] find(arr, "c")! // 2 find(arr, "d") // nilобновление для Swift 2.0:
старый
findфункция больше не поддерживается с Swift 2.0!С Swift 2.0,
Arrayполучает возможность найти индекс элемент, использующий функцию, определенную в расширенииCollectionType(гдеArrayреализует):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({ > 5}) // 5 let indexOfFirstGreaterThanOneHundred = arr2.indexOf({ > 100}) // nilобратите внимание, что эти две функции возвращают необязательные значения, как
findраньше.обновление для Swift 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 })обновление для Swift 4.2:
С Swift 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
я думаю, что стоит упомянуть, что со ссылочными типами (
class) вы можете выполнить личность сравнение, в таком случае вам просто нужно использовать===оператор идентификации в замыкании предиката:
Swift 3 / Swift 4:
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.index{ === person1} // 0 let indexOfPerson2 = people.index{ === person2} // 1 let indexOfPerson3 = people.index{ === person3} // 2 let indexOfPerson4 = people.index{ === person4} // nilобратите внимание, что приведенный выше синтаксис использует синтаксис конечных замыканий и эквивалентен:
let indexOfPerson1 = people.index(where: { === person1})
Swift 2-the
indexсинтаксис функции раньше был:let indexOfPerson1 = people.indexOf{ === person1}
* обратите внимание на соответствующие и полезные комментарий by paulbailey о
classтипы, которые реализуютEquatable, где вам нужно рассмотреть, следует ли сравнивать с помощью===(личность оператора) или==(равенство оператор). Если вы решили соответствовать с помощью==, то вы можете просто использовать метод, предложенный другим (people.index(of: person1)).
вы можете
filterмассив с замком:var myList = [1, 2, 3, 4] var filtered = myList.filter { == 3 } // <= returns [3]и вы можете посчитать массив:
filtered.count // <= returns 1так что вы можете определить если массив включает в себя ваш элемент, объединив их:
myList.filter { == 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 } }EDIT
пока мы на нем, для забавного упражнения давайте расширим
Arrayиметь afindспособ:extension Array { func find(includedElement: T -> Bool) -> Int? { for (idx, element) in enumerate(self) { if includedElement(element) { return idx } } return nil } }теперь мы можем сделать это:
myList.find { == 3 } // returns the index position of 3 or nil if not found
пока
indexOf()работает, он возвращает только один индекс.Я искал элегантный способ получить массив индексов для элементов, которые удовлетворяют некоторым условиям.
вот как это можно сделать:
Swift 3:
let array = ["apple", "dog", "log"] let indexes = array.enumerated().filter { .element.contains("og") }.map{.offset} print(indexes)Swift 2:
let array = ["apple", "dog", "log"] let indexes = array.enumerate().filter { .element.containsString("og") }.map{.index} print(indexes)
для пользовательского класса необходимо реализовать эквивалентный протокол.
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)
обновление для Swift 2:
последовательности.содержит(элемент): возвращает true, если задана последовательность (например массив) содержит указанный элемент.
Swift 1:
Если вы хотите просто проверить, содержится ли элемент внутри массива, то есть просто получить логический индикатор, используйте
contains(sequence, element)вместоfind(array, element):содержит(последовательность, элемент): Возвращает true, если задана последовательность (например массив) содержит указанный элемент.
см. пример ниже:
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. }
Swift 4.2
func index(of element: Element) -> Int? var alphabets = ["A", "B", "E", "D"]Example1
let index = alphabets.index(where: { == "A"})Example2
if let i = alphabets.index(of: "E") { alphabets[i] = "C" // i is the index } print(alphabets) // Prints "["A", "B", "C", "D"]"
в Swift 2 (с Xcode 7),
Arrayвключает в себяindexOfметодCollectionTypeпротокол. (На самом деле, дваindexOfметоды - тот, который использует равенство, чтобы соответствовать аргументу, и другое который использует закрытие.)до Swift 2 не было способа для универсальных типов, таких как коллекции, предоставлять методы для конкретных типов, полученных из них (например, массивы). Итак, в Swift 1.x, "индекс" является глобальной функцией... И он был переименован, так что в Swift 1.x, эта глобальная функция называется
find.также можно (но не обязательно) использовать
indexOfObjectметодNSArray... или любой другой, более сложный поиск meth dis от Foundation, который не имеет эквивалентов в стандартной библиотеке Swift. Простоimport Foundation(или другой модуль, который транзитивно импортирует Foundation), бросьте свойArrayдоNSArray, и вы можете использовать многие методы поиска наNSArray.
на Swift 4, если вы проходите через массив DataModel, убедитесь , что ваша модель данных соответствует протоколу Equatable , реализуйте метод lhs=rhs, и только тогда вы можете использовать ".индекс(компании" . Например
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)
вы также можете использовать функциональную библиотеку Dollar, чтобы сделать indexOf на массиве как таковой http://www.dollarswift.org/#indexof-indexof
$.indexOf([1, 2, 3, 1, 2, 3], value: 2) => 1
Если вы все еще работаете в Swift 1.x
затем попробуйте
let testArray = ["A","B","C"] let indexOfA = find(testArray, "A") let indexOfB = find(testArray, "B") let indexOfC = find(testArray, "C")
Swift 2.1
var array = ["0","1","2","3"] if let index = array.indexOf("1") { array.removeAtIndex(index) } print(array) // ["0","2","3"]Swift 3
var array = ["0","1","2","3"] if let index = array.index(of: "1") { array.remove(at: index) } array.remove(at: 1)
любое из этих решений работает для меня
Это решение у меня есть для Swift 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 === tuesday })
Swift 4. Если Ваш массив содержит элементы типа [String: AnyObject]. Поэтому, чтобы найти индекс элемента, используйте приведенный ниже код
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)или если вы хотите найти индекс на основе ключей из словаря. Здесь массив содержит объекты класса модели и я соответствую свойству id.
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") }
для 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))!)надеюсь быть полезным
Swift 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 } }
Comments