В Swift, как я могу проверить, существует ли элемент в массиве? Xcode не имеет каких - либо предложений по contain
, include
или has
, и быстрый поиск по книге ничего не дали. Есть идеи, как это проверить? Я знаю, что есть метод, find
который возвращает номер индекса, но есть ли метод, который возвращает логическое значение, как ruby #include?
?
Пример того, что мне нужно:
var elements = [1,2,3,4,5]
if elements.contains(5) {
//do something
}
if find(elements, 5) != nil { }
не достаточно хорош?Ответы:
Свифт 2, 3, 4, 5:
contains()
является методом расширения протокола изSequenceType
(для последовательностейEquatable
элементов) , а не глобальный метод , как и в более ранних версиях.Примечания:
contains()
метод требует, чтобы элементы последовательности принялиEquatable
протокол, сравните, например , ответ Эндрюса .NSObject
подкласса, вам нужно переопределитьisEqual:
, см. Подкласс NSObject в Swift: hash vs hashValue, isEqual vs == .contains()
метод, который не требует, чтобы элементы были уравниваемыми, и принимает в качестве аргумента предикат, см., Например, Сокращение, чтобы проверить, существует ли объект в массиве для Swift? ,Swift более старые версии:
источник
Equatable
протоколу (аDictionary<String, AnyObject>
это не так). Есть второй вариант,contains()
который принимает предикат (сравните stackoverflow.com/questions/29679486/… ), возможно, вы можете использовать это, напримерif contains(array, { $0 == dict } ) ...
Для тех, кто пришел сюда в поисках поиска и удаления объекта из массива:
Свифт 1
Swift 2
Свифт 3, 4
Swift 5.2
источник
Используйте это расширение:
Использовать как:
Обновлено для Swift 2/3
Обратите внимание, что в Swift 3 (или даже 2) расширение больше не требуется, так как глобальная
contains
функция была превращена в метод расширения парыArray
, который позволяет вам выполнять одно из следующих действий:источник
Если вы проверяете, содержится ли экземпляр пользовательского класса или структуры в массиве, вам необходимо реализовать протокол Equatable , прежде чем вы сможете использовать .contains (myObject).
Например:
тогда вы можете сделать:
Совет : переопределение == должно быть на глобальном уровне, а не в вашем классе / структуре
источник
Я использовал фильтр.
Если вы хотите, вы можете сжать это до
Надеюсь, это поможет.
Обновление для Swift 2
Ура для реализации по умолчанию!
источник
(Свифт 3)
Проверьте, существует ли элемент в массиве (удовлетворяющий некоторым критериям), и если это так, продолжите работу с первым таким элементом
Если целью является:
Тогда альтернатива ,
contains(_:)
как blueprintedSequence
являетсяfirst(where:)
изSequence
:В этом надуманном примере его использование может показаться глупым, но это очень полезно, если запрашивать массивы неосновных типов элементов на предмет наличия каких-либо элементов, удовлетворяющих некоторому условию. Например
Любые операции с цепочками
.filter { ... some condition }.first
могут быть заменены наfirst(where:)
. Последний лучше демонстрирует намерение и имеет преимущества в производительности по сравнению с возможными не ленивыми устройствами.filter
, поскольку они будут проходить весь массив до извлечения (возможного) первого элемента, проходящего через фильтр.Проверьте, существует ли элемент в массиве (удовлетворяющий некоторым критериям), и, если это так, удалите первый такой элемент
Комментарий ниже запросов:
Вариант использования, аналогичный приведенному выше, состоит в удалении первого элемента, который удовлетворяет данному предикату. Для этого можно использовать
index(where:)
методCollection
(который легко доступен для сбора массивов), чтобы найти индекс первого элемента, выполняющего предикат, после чего индекс можно использовать сremove(at:)
методомArray
to (возможно; при условии, что он существует) удалить этот элемент.Или, если вы хотите удалить элемент из массива и работать с ним , примените метод
Optional
: s,map(_:)
чтобы условно (для.some(...)
возврата изindex(where:)
) использовать результат изindex(where:)
для удаления и захвата удаленного элемента из массива (в дополнительном предложении связывания) ,Обратите внимание, что в надуманном примере выше члены массива представляют собой простые типы значений (
String
экземпляры), поэтому использование предиката для поиска заданного члена несколько избыточно, поскольку мы могли бы просто проверить на равенство, используя более простойindex(of:)
метод, как показано в ответе @ DogCoffee's. , Однако, если применить вышеописанный подход к поиску и удалениюPerson
,index(where:)
то целесообразно использовать с предикатом (поскольку мы больше не проверяем равенство, а выполняем предоставленный предикат).источник
Самый простой способ сделать это - использовать фильтр в массиве.
result
будет иметь найденный элемент, если он существует, и будет пустым, если элемент не существует. Так что простая проверкаresult
пустости покажет вам, существует ли элемент в массиве. Я бы использовал следующее:источник
let result = elements.filter { $0==5 }.first
должно выполнить то, что вы ищете.Свифт 4/5
Еще один способ добиться этого с помощью функции фильтра
источник
Начиная с Swift 2.1 NSArrays
containsObject
можно использовать следующим образом:источник
На всякий случай, если кто-то пытается найти,
indexPath
находится ли среди выбранных (как вUICollectionView
илиUITableView
cellForItemAtIndexPath
функции):источник
массив
Проверьте наличие элементов
Получить индекс элементов
Получить количество элементов
источник
Вот мое небольшое расширение, которое я только что написал, чтобы проверить, содержит ли мой массив делегатов объект делегата или нет ( Swift 2 ). :) Это также работает с типами значений, как шарм.
Если у вас есть идея, как оптимизировать этот код, просто дайте мне знать.
источник
если пользователь находит определенные элементы массива, используйте приведенный ниже код, такой же, как целочисленное значение.
источник
стриж
Если вы не используете объект, то вы можете использовать этот код для содержит.
Если вы используете NSObject Class в Swift. Эта переменная соответствует моему требованию. Вы можете изменить по вашему требованию.
Это для того же типа данных.
Если вы хотите, чтобы AnyObject типа.
Полное состояние
источник
как насчет использования хеш-таблицы для работы, как это?
во-первых, создание универсальной функции «карты хешей», расширяющей протокол Sequence.
Это расширение будет работать до тех пор, пока элементы в массиве соответствуют Hashable, как целые числа или строки, вот использование ...
Но сейчас давайте сосредоточимся на проверке, находится ли элемент в массиве.
источник
Swift 4.2 +
Вы можете легко проверить, является ли ваш экземпляр массивом или нет, с помощью следующей функции.
Даже вы можете получить к нему доступ следующим образом. Вы получите,
nil
если объект не будет массивом.источник