Как проверить, находится ли элемент в массиве
В Swift, как я могу проверить, существует ли элемент в массиве? У Xcode нет предложений по contain
, include
или has
, а быстрый поиск в книге ничего не отображается. Любая идея, как проверить это? Я знаю, что есть метод find
который возвращает номер индекса, но есть ли метод, который возвращает логическое значение, например, #include?
ruby #include?
?
Пример того, что мне нужно:
var elements = [1,2,3,4,5] if elements.contains(5) { //do something }
- Есть ли у JavaScript метод, подобный «range ()» для создания диапазона в пределах предоставленных границ?
- байтовый массив в короткий массив и обратно в java
- Правильное распределение многомерных массивов
- «Невозможно создать общий массив ...» - как создать массив карт ?
- печать всего содержимого массива в C #
- Почему я не могу обработать массив как указатель в C?
- mongodb найти несколько элементов массива
- Как разбирать массив JSON с помощью Gson
- Как инициализировать std :: array элегантно, если T не является конструктивным по умолчанию?
- Найти сходство косинусов между двумя массивами
- сортировка 2D-массива String в java
- Java-создание байтового массива, размер которого представлен длинным
- Как выводить сериализованные данные представления JSON в виде массива объектов, а не обертывать внешний объект?
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)
Проверьте, существует ли элемент в массиве (выполнение некоторых критериев), и если да, продолжайте работать с первым таким элементом
Если это намерение:
- Чтобы проверить, существует ли элемент в массиве (/ выполняет некоторые логические критерии, не обязательно проверку равенства)
- И если это так, приступайте и работайте с первым таким элементом,
Тогда альтернатива 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