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

В 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), а не глобальный метод, как в предыдущих выпусках.

Примечания:

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)

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

Если целью является:

  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, поскольку они будут проходить весь массив до извлечения (возможного) первого элемента, проходящего фильтр.


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

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

Как я могу удалить 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