Есть ли у Swift что-то вроде _.findWhere в Underscore.js?
У меня есть массив структур типа T
и хотел бы проверить, содержит ли массив объект структуры, name
свойство которого равно Foo
.
Пытались использовать find()
и , filter()
но они работают только с примитивными типами, например , String
или Int
. Выдает ошибку о несоответствии Equitable
протоколу или что-то в этом роде.
Ответы:
FWIW, если вы не хотите использовать пользовательскую функцию или расширение, вы можете:
name
Сначала генерируется массив, а затемfind
из него.Если у вас огромный массив, вы можете сделать:
или, может быть:
источник
SWIFT 5
Проверьте, существует ли элемент
Получить элемент
Получить элемент и его смещение
Получить смещение
источник
$0.name == "foo"
одну операцию и$0.name == "boo"
другую операциюВы можете использовать
index
методArray
с предикатом ( см. Документацию Apple здесь ).Для вашего конкретного примера это будет:
Swift 5.0
Swift 3.0
Swift 2.0
источник
Swift 3
Если вам нужен объект, используйте:
(Если у вас есть более одного объекта с именем «Foo», тогда
first
вернет первый объект из неопределенного порядка)источник
array.first {$0.name == "Foo"}
array.first(where: {$0.name == "Foo"})
Вы можете отфильтровать массив, а затем просто выбрать первый элемент, как показано в разделе « Найти объект со свойством в массиве» .
Или вы определяете пользовательское расширение
Пример использования:
В Swift 3 вы можете использовать существующий
first(where:)
метод (как упомянуто в комментарии ):источник
array.lazy.filter( predicate ).first
? Насколько эффективен .lazy для небольших массивов?filter
всегда равна,O(n)
тогда как вfindFirstMatching
только в худшем случае (когда искомый элемент является последним или не находится в массиве вообще). 2.filter
создает совершенно новый массив фильтруемых элементов, в то время какfindFirstMatching
just возвращает запрошенный элемент.Swift 3.0
Swift 2.1
Фильтрация в свойствах объекта теперь поддерживается в Swift 2.1. Вы можете фильтровать ваш массив на основе любого значения структуры или класса, вот пример
ИЛИ
источник
Swift 4 ,
Еще один способ добиться этого с помощью функции фильтра,
источник
Swift 3
Вы можете использовать индекс (где :) в Swift 3
пример
источник
$0.name == "Foo"
?Swift 3
источник
Swift 2 или позже
Вы можете объединить
indexOf
иmap
написать функцию «найти элемент» в одну строку.Использование
filter
+first
выглядит чище, ноfilter
оценивает все элементы в массиве.indexOf
+map
выглядит сложно, но оценка останавливается, когда найдено первое совпадение в массиве. Оба подхода имеют свои плюсы и минусы.источник
Используйте
contains
:Или вы можете попробовать то, на что указал вам Мартин, в комментариях и
filter
попробовать еще раз: Найти объект со свойством в массиве .источник
item
того же типа, что и элемент в массиве. Тем не менее, все, что у меня есть, это просто названиеview.annotation.title
. Мне нужно сравнить элементы в массиве по этому названию.if contains(yourArray, view.annotation.title) { // code goes here }
.Другой способ получить доступ к array.index (of: Any) - объявить ваш объект
источник
Используйте Доллар, который является Lo-Dash или Underscore.js для Swift:
источник
Свифт 3:
Вы можете использовать встроенную функциональность Swifts для поиска пользовательских объектов в массиве.
Сначала вы должны убедиться, что ваш пользовательский объект соответствует протоколу : Equatable .
С функцией Equatable, добавленной к вашему объекту, Swift теперь покажет вам дополнительные свойства, которые вы можете использовать в массиве:
источник
Для Swift 3,
источник
Например, если у нас был массив чисел:
Мы могли бы найти первое нечетное число, как это:
Это отправит обратно 4 в качестве необязательного целого числа, потому что первое нечетное число (9) находится в индексе четыре.
источник