Swift - Как получить индексы фильтрованных элементов массива
let items: [String] = ["A", "B", "A", "C", "A", "D"]
items.whatFunction("A") // -> [0, 2, 4]
items.whatFunction("B") // -> [1]
Поддерживает ли Swift 3 такую функцию, как whatFunction(_: Element)
?
Если нет, то какая наиболее эффективная логика?
Ответы
Ответ 1
Вы можете создать собственное расширение для массивов.
extension Array where Element: Equatable {
func indexes(of element: Element) -> [Int] {
return self.enumerated().filter({ element == $0.element }).map({ $0.offset })
}
}
Вы можете просто называть это следующим образом
items.indexes(of: "A") // [0, 2, 4]
items.indexes(of: "B") // [1]
Ответ 2
Вы можете напрямую фильтровать indices
массива, это исключает дополнительный пинг map
.
let items = ["A", "B", "A", "C", "A", "D"]
let filteredIndices = items.indices.filter {items[$0] == "A"}
или как расширение Array
:
extension Array where Element: Equatable {
func whatFunction(_ value : Element) -> [Int] {
return self.indices.filter {self[$0] == value}
}
}
items.whatFunction("A") // -> [0, 2, 4]
items.whatFunction("B") // -> [1]
или еще более общий
extension Collection where Element: Equatable {
func whatFunction(_ value : Element) -> [Index] {
return self.indices.filter {self[$0] == value}
}
}
Ответ 3
Вы можете достичь этого с помощью цепочки:
-
enumerated()
- добавить индексы; -
filter()
ненужные элементы; -
map()
наши индексы.
Пример (работает в Swift 3 - Swift 4.x):
let items: [String] = ["A", "B", "A", "C", "A", "D"]
print(items.enumerated().filter({ $0.element == "A" }).map({ $0.offset })) // -> [0, 2, 4]
Другой способ - использовать flatMap
, который позволяет проверить элемент и вернуть индекс, если необходимо, в одном замыкании.
Пример (работает в Swift 3 - Swift 4.0):
print(items.enumerated().flatMap { $0.element == "A" ? $0.offset : nil }) // -> [0, 2, 4]
Но начиная с Swift 4.1 flatMap
который может возвращать объекты, отличные от nil, устарели, и вместо этого вы должны использовать compactMap
.
Пример (работает с Swift 4.1):
print(items.enumerated().compactMap { $0.element == "A" ? $0.offset : nil }) // -> [0, 2, 4]
И самый чистый и самый дешевый способ - это перебирать индексы массива и проверять, равен ли элемент массива в текущем индексе требуемому элементу.
Пример (работает в Swift 3 - Swift 4.x):
print(items.indices.filter({ items[$0] == "A" })) // -> [0, 2, 4]
Ответ 4
В Swift 3 и Swift 4 вы можете сделать это:
let items: [String] = ["A", "B", "A", "C", "A", "D"]
extension Array where Element: Equatable {
func indexes(of item: Element) -> [Int] {
return enumerated().compactMap { $0.element == item ? $0.offset : nil }
}
}
items.indexes(of: "A")
Я надеюсь, что мой ответ был полезным 😊
Ответ 5
вы можете использовать его так:
let items: [String] = ["A", "B", "A", "C", "A", "D"]
let indexes = items.enumerated().filter {
$0.element == "A"
}.map{$0.offset}
print(indexes)
Ответ 6
просто скопируйте и вставьте
extension Array {
func whatFunction(_ ids : String) -> [Int] {
var mutableArr = [Int]()
for i in 0..<self.count {
if ((self[i] as! String) == ids) {
mutableArr.append(i)
}
}
return mutableArr
}
}
Ответ 7
Например, поиск индексов значений p_last в массиве inds1: (swift 4+)
let p_last = [51,42]
let inds1 = [1,3,51,42,4]
let idx1 = Array(inds1.filter{ p_last.contains($0) }.indices)
idx1 = [0,1]