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



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



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



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

14 ответов:

Swift 2, 3, 4:

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")
}

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

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)

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

если намерение является:

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

затем альтернатива contains(_:) как blueprinted Sequence это 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:) метод Array to (возможно; учитывая, что он существует) удалите этот элемент.

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: s map(_:) метод условно (для .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

    Ничего не найдено.