Swift - 如何获取数组的过滤项的索引

Byo*_*oth 20 arrays swift swift3 swift4

let items: [String] = ["A", "B", "A", "C", "A", "D"]

items.whatFunction("A") // -> [0, 2, 4]
items.whatFunction("B") // -> [1]
Run Code Online (Sandbox Code Playgroud)

Swift 3是否支持这样的功能whatFunction(_: Element)

如果没有,最有效的逻辑是什么?

vad*_*ian 23

您可以indices直接过滤数组,避免额外的mapping.

let items = ["A", "B", "A", "C", "A", "D"]
let filteredIndices = items.indices.filter {items[$0] == "A"}
Run Code Online (Sandbox Code Playgroud)

或作为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]
Run Code Online (Sandbox Code Playgroud)

或者更通用

extension Collection where Element: Equatable {

    func whatFunction(_ value :  Element) -> [Index] {
        return self.indices.filter {self[$0] == value}
    }

}
Run Code Online (Sandbox Code Playgroud)


Yan*_*ick 16

您可以为阵列创建自己的扩展.

extension Array where Element: Equatable {
    func indexes(of element: Element) -> [Int] {
        return self.enumerated().filter({ element == $0.element }).map({ $0.offset })
    }
}
Run Code Online (Sandbox Code Playgroud)

你可以简单地这样称呼它

items.indexes(of: "A") // [0, 2, 4]
items.indexes(of: "B") // [1]
Run Code Online (Sandbox Code Playgroud)


pac*_*ion 11

您可以通过以下链条实现此目的:

  1. enumerated() - 添加索引;
  2. filter() 出不必要的物品;
  3. 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]
Run Code Online (Sandbox Code Playgroud)

另一种方法是使用flatMap,它允许您在一个闭包中检查元素并返回索引(如果需要).

示例(适用于Swift 3 - Swift 4.0):

print(items.enumerated().flatMap { $0.element == "A" ? $0.offset : nil }) // -> [0, 2, 4]
Run Code Online (Sandbox Code Playgroud)

但是,由于flatMap可以返回非零对象的Swift 4.1 变得弃用,而是应该使用compactMap.

示例(自Swift 4.1起作用):

print(items.enumerated().compactMap { $0.element == "A" ? $0.offset : nil }) // -> [0, 2, 4]
Run Code Online (Sandbox Code Playgroud)

最干净,最便宜的内存方式是迭代数组索引并检查当前索引处的数组元素是否等于所需元素.

示例(适用于Swift 3 - Swift 4.x):

print(items.indices.filter({ items[$0] == "A" })) // -> [0, 2, 4]
Run Code Online (Sandbox Code Playgroud)


Jul*_*ode 9

Swift 3Swift 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")
Run Code Online (Sandbox Code Playgroud)

我希望我的回答很有帮助