Как проверить, находится ли элемент в массиве

В Swift, как я могу проверить, существует ли элемент в массиве? У Xcode нет предложений по contain , include или has , а быстрый поиск в книге ничего не отображается. Любая идея, как проверить это? Я знаю, что есть метод find который возвращает номер индекса, но есть ли метод, который возвращает логическое значение, например, #include? ruby #include? ?

Пример того, что мне нужно:

 var elements = [1,2,3,4,5] if elements.contains(5) { //do something } 

Swift 2, 3, 4:

 let elements = [1, 2, 3, 4, 5] if elements.contains(5) { print("yes") } 

contains() – это метод расширения протокола SequenceType (для последовательностей Equatable ), а не глобальный метод, как в предыдущих версиях.

Примечания:

  • Этот метод contains() требует, чтобы элементы последовательности приняли Equatable protocol, сравните, например , ответ Эндрюса .
  • Если элементы последовательности являются экземплярами подclassа isEqual: , тогда вы должны переопределить isEqual: см. Подclass NSObject в Swift: hash vs hashValue, isEqual vs == .
  • Существует еще один – более общий – contains() метод, который не требует, чтобы элементы были равномерными, и принимает предикат в качестве аргумента, см., Например, Shorthand, чтобы проверить, существует ли объект в массиве для Swift? ,

Быстрые версии:

 let elements = [1,2,3,4,5] if contains(elements, 5) { println("yes") } 

Для тех, кто пришел сюда, ища поиск и удаляет объект из массива:

Swift 1

 if let index = find(itemList, item) { itemList.removeAtIndex(index) } 

Swift 2

 if let index = itemList.indexOf(item) { itemList.removeAtIndex(index) } 

Swift 3, 4

 if let index = itemList.index(of: item) { itemList.remove(at: index) } 

Используйте это расширение:

 extension Array { func contains(obj: T) -> Bool { return self.filter({$0 as? T == obj}).count > 0 } } 

Использовать как:

 array.contains(1) 

Обновлено для Swift 2/3

Обратите внимание, что с Swift 3 (или даже 2) расширение больше не требуется, так как глобальная функция contains функцию расширения в Array , которая позволяет вам выполнить одно из следующих действий:

 let a = [ 1, 2, 3, 4 ] a.contains(2) // => true, only usable if Element : Equatable a.contains { $0 < 1 } // => false 

Если вы проверяете, содержится ли экземпляр настраиваемого classа или структуры в массиве, вам необходимо реализовать протокол Equatable , прежде чем вы сможете использовать .contains (myObject).

Например:

 struct Cup: Equatable { let filled:Bool } static func ==(lhs:Cup, rhs:Cup) -> Bool { // Implement Equatable return lhs.filled == rhs.filled } 

то вы можете сделать:

 cupArray.contains(myCup) 

Совет . == переопределение должно быть на глобальном уровне, а не внутри вашего classа / структуры

Я использовал фильтр.

 let results = elements.filter { el in el == 5 } if results.count > 0 { // any matching items are in results } else { // not found } 

Если вы хотите, вы можете сжать это

 if elements.filter({ el in el == 5 }).count > 0 { } 

Надеюсь, это поможет.


Обновление для Swift 2

Ура для реализаций по умолчанию!

 if elements.contains(5) { // any matching items are in results } else { // not found } 

(Swift 3)

Проверьте, существует ли элемент в массиве (выполнение некоторых критериев), и если да, продолжайте работать с первым таким элементом

Если это намерение:

  1. Чтобы проверить, существует ли элемент в массиве (/ выполняет некоторые логические критерии, не обязательно проверку равенства)
  2. И если это так, приступайте и работайте с первым таким элементом,

Тогда альтернатива contains(_:) как синтаксическая Sequence first(where:) Sequence :

 let elements = [1, 2, 3, 4, 5] if let firstSuchElement = elements.first(where: { $0 == 4 }) { print(firstSuchElement) // 4 // ... } 

В этом надуманном примере его использование может показаться глупым, но очень полезно, если запрашивать массивы не фундаментальных типов элементов для существования каких-либо элементов, выполняющих какое-либо условие. Например

 struct Person { let age: Int let name: String init(_ age: Int, _ name: String) { self.age = age self.name = name } } let persons = [Person(17, "Fred"), Person(16, "Susan"), Person(19, "Hannah"), Person(18, "Sarah"), Person(23, "Sam"), Person(18, "Jane")] if let eligableDriver = persons.first(where: { $0.age >= 18 }) { print("\(eligableDriver.name) can possibly drive the rental car in Sweden.") // ... } // Hannah can possibly drive the rental car in Sweden. let daniel = Person(18, "Daniel") if let sameAgeAsDaniel = persons.first(where: { $0.age == daniel.age }) { print("\(sameAgeAsDaniel.name) is the same age as \(daniel.name).") // ... } // Sarah is the same age as Daniel. 

Любые связанные операции с использованием .filter { ... some condition }.first можно выгодно заменить first(where:) . Последнее показывает намерение лучше и обладает преимуществами производительности по сравнению с возможными .filter устройствами .filter они передадут полный массив до извлечения (возможного) первого элемента, проходящего фильтр.


Проверьте, существует ли элемент в массиве (выполнение некоторых критериев), и если это так, удалите первый такой элемент

Комментарий ниже запросов:

Как я могу удалить firstSuchElement из массива?

Аналогичным вариантом использования вышеприведенного является удаление первого элемента, который выполняет заданный предикат. Для этого можно найти index(where:) метод Collection (который легко доступен для коллекции массива), чтобы найти индекс первого элемента, выполняющего предикат, после чего индекс можно использовать с remove(at:) метод Array (возможно, учитывая, что он существует) удаляет этот элемент.

 var elements = ["a", "b", "c", "d", "e", "a", "b", "c"] if let indexOfFirstSuchElement = elements.index(where: { $0 == "c" }) { elements.remove(at: indexOfFirstSuchElement) print(elements) // ["a", "b", "d", "e", "a", "b", "c"] } 

Или, если вы хотите удалить элемент из массива и работать с ним , примените Optional : s map(_:) метод условно (для .some(...) return from index(where:) ) использовать результат из index(where:) для удаления и захвата удаленного элемента из массива (в необязательном предложении привязки).

 var elements = ["a", "b", "c", "d", "e", "a", "b", "c"] if let firstSuchElement = elements.index(where: { $0 == "c" }) .map({ elements.remove(at: $0) }) { // if we enter here, the first such element have now been // remove from the array print(elements) // ["a", "b", "d", "e", "a", "b", "c"] // and we may work with it print(firstSuchElement) // c } 

Обратите внимание, что в надуманном примере выше элементы массива представляют собой простые типы значений (экземпляры String ), поэтому использование предиката для поиска данного члена несколько завышено, поскольку мы можем просто проверить равенство, используя более простой метод index(of:) как показано в ответе @ DogCoffee . Однако, применяя подход find-and-remove выше к примеру Person , использование index(where:) с предикатом является подходящим (поскольку мы больше не проверяем равенство, а выполняем поставленный предикат).

Самый простой способ сделать это – использовать фильтр в массиве.

 let result = elements.filter { $0==5 } 

result будет иметь найденный элемент, если он существует и будет пустым, если элемент не существует. Поэтому, просто проверяя, является ли result пустым, вы узнаете, существует ли элемент в массиве. Я бы использовал следующее:

 if result.isEmpty { // element does not exist in array } else { // element exists } 

С Swift 2.1 NSArrays containsObject объект, который можно использовать так:

 if myArray.containsObject(objectImCheckingFor){ //myArray has the objectImCheckingFor } 

На всякий случай кто-то пытается найти, если indexPath входит в число выбранных (например, в UICollectionView или UITableView cellForItemAtIndexPath ):

  var isSelectedItem = false if let selectedIndexPaths = collectionView.indexPathsForSelectedItems() as? [NSIndexPath]{ if contains(selectedIndexPaths, indexPath) { isSelectedItem = true } } 

Вот мое небольшое расширение, которое я только что написал, чтобы проверить, содержит ли мой массив делегатов объект-делегат или нет ( Swift 2 ). 🙂 Он также работает с типами значений, такими как шарм.

 extension Array { func containsObject(object: Any) -> Bool { if let anObject: AnyObject = object as? AnyObject { for obj in self { if let anObj: AnyObject = obj as? AnyObject { if anObj === anObject { return true } } } } return false } } 

Если у вас есть идея, как оптимизировать этот код, чем просто дайте мне знать.

стриж

Если вы не используете объект, вы можете использовать этот код для этого пользователя.

 let elements = [ 10, 20, 30, 40, 50] if elements.contains(50) { print("true") } 

Если вы используете NSObject Class в swift. Эти переменные соответствуют моим требованиям. вы можете изменить свое требование.

 var cliectScreenList = [ATModelLeadInfo]() var cliectScreenSelectedObject: ATModelLeadInfo! 

Это относится к одному типу данных.

 { $0.user_id == cliectScreenSelectedObject.user_id } 

Если вы хотите тип AnyObject.

 { "\($0.user_id)" == "\(cliectScreenSelectedObject.user_id)" } 

Полное состояние

 if cliectScreenSelected.contains( { $0.user_id == cliectScreenSelectedObject.user_id } ) == false { cliectScreenSelected.append(cliectScreenSelectedObject) print("Object Added") } else { print("Object already exists") } 

если пользователь найдет определенные элементы массива, используйте ниже код так же, как целое значение.

 var arrelemnts = ["sachin", "test", "test1", "test3"] if arrelemnts.contains("test"){ print("found") }else{ print("not found") } 

Swift 4, еще один способ добиться этого, с функцией фильтра

var elements = [1,2,3,4,5]

  if let object = elements.filter({ $0 == 5 }).first { print("found") } else { print("not found") } 

как насчет использования хеш-таблицы для работы, как это?

во-первых, создание общей функции «hash-карта», расширяющей протокол Sequence.

 extension Sequence where Element: Hashable { func hashMap() -> [Element: Int] { var dict: [Element: Int] = [:] for (i, value) in self.enumerated() { dict[value] = i } return dict } } 

Это расширение будет работать до тех пор, пока элементы массива соответствуют Hashable, например целые числа или строки, вот использование …

 let numbers = Array(0...50) let hashMappedNumbers = numbers.hashMap() let numToDetect = 35 let indexOfnumToDetect = hashMappedNumbers[numToDetect] // returns the index of the item and if all the elements in the array are different, it will work to get the index of the object! print(indexOfnumToDetect) // prints 35 

Но пока давайте просто сосредоточимся на проверке, находится ли элемент в массиве.

 let numExists = indexOfnumToDetect != nil // if the key does not exist means the number is not contained in the collection. print(numExists) // prints true 
  • Проверьте, существует ли значение в массиве Postgres
  • Получить JSONArray без имени массива?
  • Android-создать JSON-массив и объект JSON
  • Адрес массива
  • В Perl, как я могу найти индекс заданного значения в массиве?
  • Создание массива из диапазона в VBA
  • Поместить и получить массив String из общих настроек
  • NullPointerException при создании массива объектов
  • Где задано свойство длины массива?
  • printf добавляет дополнительный `FFFFFF` к шестнадцатеричной печати из массива char
  • Почему awk, похоже, рандомизирует массив?
  • Давайте будем гением компьютера.