Как проверить, если элемент в массиве
в Swift, как я могу проверить, если элемент существует в массиве? Xcode не имеет никаких предложений для contain,include или has, и быстрый поиск по книге ничего не нашел. Есть идеи, как это проверить? Я знаю, что есть метод find это возвращает номер индекса, но есть ли метод, который возвращает логическое значение, такое как ruby's #include??
пример того, что мне нужно:
var elements = [1,2,3,4,5]
if elements.contains(5) {
//do something
}
14 ответов:
Swift 2, 3, 4:
let elements = [1, 2, 3, 4, 5] if elements.contains(5) { print("yes") }
contains()это метод расширения протокола наSequenceType(для последовательностиEquatableэлементы), а не глобальный метод, как в предыдущие версии.Примечания:
- этой
contains()метод требует, чтобы элементы последовательности принятьEquatableпротокол, сравнить например ответ Эндрюса.- если последовательность элементы являются экземплярами
NSObjectподкласс тогда вы должны переопределитьisEqual:см. подкласс NSObject в Swift: hash vs hashValue, isEqual vs ==.- есть еще один-более общий -
contains()метод, который не требует, чтобы элементы были равны и принимает предикат как аргумент, см., например,Стенография, чтобы проверить, существует ли объект в массиве для Swift?.старые версии 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<T where T : Equatable>(obj: T) -> Bool { return self.filter({ 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 { < 1 } // => false
Если вы проверяете, если экземпляр пользовательский класс или struct содержится в массиве, вам понадобится использовать тег Equatable протокол, прежде чем вы можете использовать .содержит (myObject).
например:
struct Cup: Equatable { let filled:Bool } static func ==(lhs:Cup, rhs:Cup) -> Bool { // Implement Equatable return lhs.filled == rhs.filled }затем вы можете сделать:
cupArray.contains(myCup)Совет: переопределение == должно быть на глобальном уровне, а не в вашем классе/структуре
я использовал фильтр.
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(_:)как blueprintedSequenceэтоfirst(where:)наSequence:let elements = [1, 2, 3, 4, 5] if let firstSuchElement = elements.first(where: { == 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: { .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: { .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, так как они передадут полный массив до извлечения (возможного) первого элемента, проходящего фильтр.
проверьте, существует ли элемент в массиве (выполняя некоторые критерии),и если да, то удалите первый такой элемент
комментарий ниже запросы:
как я могу удалить
firstSuchElementиз массива?подобный случай использования одного выше-это удалить первый элемент, который удовлетворяет заданному предикату. Чтобы сделать это, то
index(where:)методCollection(который легко доступен для коллекции массивов) может быть использован для поиска индекса первого элемента, выполняющего предикат, после чего индекс может быть использован сremove(at:)методArrayto (возможно; учитывая, что он существует) удалите этот элемент.var elements = ["a", "b", "c", "d", "e", "a", "b", "c"] if let indexOfFirstSuchElement = elements.index(where: { == "c" }) { elements.remove(at: indexOfFirstSuchElement) print(elements) // ["a", "b", "d", "e", "a", "b", "c"] }или, если вы хотите удалить элемент из массива С применить
Optional: smap(_:)метод условно (для.some(...)вернуться изindex(where:)) использовать результатindex(where:)для удаления и захвата удаленного элемента из массива (в необязательном предложении привязки).var elements = ["a", "b", "c", "d", "e", "a", "b", "c"] if let firstSuchElement = elements.index(where: { == "c" }) .map({ elements.remove(at: ) }) { // 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:)метод, как показано в @Doggoffee's answer. Если применить подход "найти и удалить" выше кPersonпример, однако, с помощьюindex(where:)с предикатом подходит (так как мы больше не проверяем равенство, но для выполнения поставленного предиката).
самый простой способ сделать это-использовать фильтр на массиве.
let result = elements.filter { ==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илиUITableViewcellForItemAtIndexPathфункции):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 в swift. Это переменные в соответствии с моим требованием. вы можете изменить для вашего требования.
var cliectScreenList = [ATModelLeadInfo]() var cliectScreenSelectedObject: ATModelLeadInfo!Это для одного и того же типа данных.
{ .user_id == cliectScreenSelectedObject.user_id }если вы хотите AnyObject типа.
{ "\(.user_id)" == "\(cliectScreenSelectedObject.user_id)" }полное условие
if cliectScreenSelected.contains( { .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({ == 5 }).first { print("found") } else { print("not found") }
как насчет использования хэш-таблицы для работы, как это?
во-первых, создание универсальной функции "хэш-карта", расширяющей протокол последовательности.
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
Comments