Как проверить, находится ли элемент в массиве
В Swift, как я могу проверить, существует ли элемент в массиве? У Xcode нет предложений для contain
, include
или has
, и быстрый поиск в книге ничего не показал. Любая идея, как проверить это? Я знаю, что существует метод find
, который возвращает номер индекса, но есть ли метод, который возвращает логическое значение типа ruby #include?
?
Пример того, что мне нужно:
var elements = [1,2,3,4,5]
if elements.contains(5) {
//do something
}
Ответы
Ответ 1
Свифт 2, 3, 4, 5:
let elements = [1, 2, 3, 4, 5]
if elements.contains(5) {
print("yes")
}
contains()
- это метод расширения протокола SequenceType
(для последовательностей элементов Equatable
), а не глобальный метод, как в предыдущих выпусках.
Примечания:
- Этот метод
contains()
требует, чтобы элементы последовательности приняли протокол Equatable
, сравните, например, ответ Эндрюса. - Если элементы последовательности являются экземпляры
NSObject
подкласса, то вы должны переопределить isEqual:
см NSObject подкласс в Swift: хэш против значения хэша, IsEqual против ==. - Существует еще один, более общий, метод with
contains()
который не требует выравнивания элементов и принимает предикат в качестве аргумента, см., Например, Сокращение, чтобы проверить, существует ли объект в массиве для Swift? ,
Swift старых версий:
let elements = [1,2,3,4,5]
if contains(elements, 5) {
println("yes")
}
Ответ 2
Для тех, кто пришел сюда в поисках поиска и удаления объекта из массива:
Свифт 1
if let index = find(itemList, item) {
itemList.removeAtIndex(index)
}
Swift 2
if let index = itemList.indexOf(item) {
itemList.removeAtIndex(index)
}
Свифт 3, 4, 5
if let index = itemList.index(of: item) {
itemList.remove(at: index)
}
Ответ 3
Используйте это расширение:
extension Array {
func contains<T where T : Equatable>(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
Ответ 4
Если вы проверяете, содержится ли экземпляр настраиваемого класса или структуры в массиве, перед тем как вы сможете использовать протокол 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)
Совет: переопределение == должно находиться на глобальном уровне, а не внутри вашего класса/структуры
Ответ 5
Я использовал фильтр.
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
}
Ответ 6
(Свифт 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
, поскольку они будут проходить весь массив до извлечения (возможного) первого элемента, проходящего фильтр.
Проверьте, существует ли элемент в массиве (удовлетворяющий некоторым критериям), и, если так, удалите первый такой элемент
Комментарий ниже запросов:
Как я могу удалить 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(...)
возврата из 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. Однако, если применить приведенный выше подход к поиску и удалению к примеру Person
, следует использовать index(where:)
с предикатом (поскольку мы больше не проверяем равенство, а выполняем предоставленный предикат).
Ответ 7
Самый простой способ сделать это - использовать фильтр в массиве.
let result = elements.filter { $0==5 }
result
будет иметь найденный элемент, если он существует и будет пустым, если элемент не существует. Поэтому, просто проверяя, является ли result
пустым, вы узнаете, существует ли элемент в массиве. Я бы использовал следующее:
if result.isEmpty {
// element does not exist in array
} else {
// element exists
}
Ответ 8
С Swift 2.1 NSArrays имеют containsObject
, которые можно использовать так:
if myArray.containsObject(objectImCheckingFor){
//myArray has the objectImCheckingFor
}
Ответ 9
На всякий случай кто-то пытается найти, если indexPath
находится среди выбранных (например, в функциях UICollectionView
или UITableView
cellForItemAtIndexPath
):
var isSelectedItem = false
if let selectedIndexPaths = collectionView.indexPathsForSelectedItems() as? [NSIndexPath]{
if contains(selectedIndexPaths, indexPath) {
isSelectedItem = true
}
}
Ответ 10
Вот мое небольшое расширение, которое я только что написал, чтобы проверить, содержит ли мой массив делегатов объект-делегат или нет (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
}
}
Если у вас есть идея, как оптимизировать этот код, чем просто дайте мне знать.
Ответ 11
Swift 4, еще один способ добиться этого, с функцией фильтра
var elements = [1,2,3,4,5]
if let object = elements.filter({ $0 == 5 }).first {
print("found")
} else {
print("not found")
}
Ответ 12
если пользователь найдет определенные элементы массива, используйте ниже код так же, как целочисленное значение.
var arrelemnts = ["sachin", "test", "test1", "test3"]
if arrelemnts.contains("test"){
print("found") }else{
print("not found") }
Ответ 13
Swift
Если вы не используете объект, вы можете использовать этот код для пользователя.
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")
}
Ответ 14
как насчет использования хеш-таблицы для работы, как это?
во-первых, создание универсальной функции "карта хеша", расширяющей протокол 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
Ответ 15
Swift 4.2 +
Вы можете легко проверить, является ли ваш экземпляр массивом или нет, с помощью следующей функции.
func verifyIsObjectOfAnArray<T>(_ object: T) -> Bool {
if let _ = object as? [T] {
return true
}
return false
} .
Даже вы можете получить к нему доступ следующим образом. Вы получите Nil
если объект не будет массивом.
func verifyIsObjectOfAnArray<T>(_ object: T) -> [T]? {
if let array = object as? [T] {
return array
}
return nil
}
Ответ 16
массив
let elements = [1, 2, 3, 4, 5, 5]
Проверьте наличие элементов
elements.contains(5) // true
Получить индекс элементов
elements.firstIndex(of: 5) // 4
elements.firstIndex(of: 10) // nil
Получить количество элементов
let results = elements.filter { element in element == 5 }
results.count // 2