如何获得索引(:)返回多个索引?

时间:2018-02-05 20:48:56

标签: ios arrays swift swift4

这是一个组数组。

var group = ["H","H","E","D",
             "G","D","G","E",
             "D","B","A","B",
             "A","A","G","C",
             "C","H","D","G",
             "H","B","E","F",
             "F","C","E","A",
             "B","C","F","F"]

我想做这样的事情来找到" A"。

的索引
group.index(of: "A"!)

但是这只会返回第一个索引,但不会返回其他三个指数" A" s。

print(group.index(of: "A")!) //10

如何让程序返回" A"的所有四个索引?

8 个答案:

答案 0 :(得分:11)

您可以使用enumeratedcompactMap的组合:

let indexArray = group.enumerated().compactMap {
   $0.element == "A" ? $0.offset : nil
}    
print(indexArray) // [10, 12, 13, 27]

答案 1 :(得分:6)

或者只是枚举/过滤/映射:

 group.enumerated().filter{$1=="A"}.map{$0.offset}

[编辑]根据亚历山大的建议将$ 0.0更改为$ 0.offset(使代码更清晰/明确)

答案 2 :(得分:3)

您可以使用简单的循环

使用此代码

var group = ["H","H","E","D",
             "G","D","G","E",
             "D","B","A","B",
             "A","A","G","C",
             "C","H","D","G",
             "H","B","E","F",
             "F","C","E","A",
             "B","C","F","F"]
var indexes : [Int] = []
for (index,string) in group.enumerated() {
    if(string == "A") {
        indexes.append(index)
    }
}

debugPrint(indexes)

答案 3 :(得分:2)

为了完整起见,这是filter indices

的另一种不同方法
let group = ["H","H","E","D",
             "G","D","G","E",
             "D","B","A","B",
             "A","A","G","C",
             "C","H","D","G",
             "H","B","E","F",
             "F","C","E","A",
             "B","C","F","F"]

let indices = group.indices.filter{ group[$0] == "A"}

答案 4 :(得分:1)

基于reduce通用的解决方案:

let group = ["H","H","E","D",
             "G","D","G","E",
             "D","B","A","B",
             "A","A","G","C",
             "C","H","D","G",
             "H","B","E","F",
             "F","C","E","A",
             "B","C","F","F"]

extension Array where Element: Equatable {
    func indexes(of element: Element) -> [Index] {
        return enumerated().reduce([]) { $1.element == element ? $0 + [$1.offset] : $0 }
    }
}

group.indexes(of: "A") // 10, 12, 13, 27]

另一种方法是建立一个字母到索引字典并查询:

let indices = Dictionary(group.enumerated().map { ($1, [$0]) }, uniquingKeysWith: +)
indices["A"] ?? [] // [10, 12, 13, 27]

,但是对于这个解决方案,您需要打开结果,因为字典下标会返回一个可选值。

顺便说一句,你的数组可能是let而不是var,常量会对代码产生可预测性,我建议尽可能多地使用它们。

答案 5 :(得分:1)

Vadian的回答above已经是最简洁的了。

其余的答案只是围绕链式HUF跳舞,因为它很酷但只是为了真正的完整性,因为最基本的实现显然会做到以下几点:

let group = ["H","H","E","D",
             "G","D","G","E",
             "D","B","A","B",
             "A","A","G","C",
             "C","H","D","G",
             "H","B","E","F",
             "F","C","E","A",
             "B","C","F","F"]

var array = [Int]()
for index in 0..<group.count {
    if group[index] == "A" {
        array.append(index)
    }
}

答案 6 :(得分:0)

几天后阅读了Extensions和函数式编程后,我想尝试为Array类编写扩展函数。在这里:

var group = ["H","H","E","D",
             "G","D","G","E",
             "D","B","A","B",
             "A","A","G","C",
             "C","H","D","G",
             "H","B","E","F",
             "F","C","E","A",
             "B","C","F","F"]

var group2 = [1,2,3,4,5,6,7,8]

// Create a nice Array extension method that will return indices of wanted group.

extension Array where Element: Equatable {

func showIndices(indexOf groupName: Element) -> [Int] {
    return self.enumerated().compactMap {
        $0.element == groupName ? $0.offset : nil
    }
}
}

group.showIndices(indexOf: "A")
group2.showIndices(indexOf: 1)

// [10, 12, 13, 27]
// [0]

答案 7 :(得分:0)

您可以扩展集合并创建带有谓词的索引方法。

extension Collection where Element: Equatable {
    func indices(where predicate: @escaping (Element) throws -> Bool) rethrows -> [Index] {
        try self.indices.filter({try predicate(self[$0])})
    }
    func indices(of element: Element) -> [Index] {
        self.indices.filter({self[$0] == element})
    }
}

对于被Int索引的集合,您可以返回IndexSet:

extension Collection where Element: Equatable, Index == Int {
    func indexSet(where predicate: @escaping (Element) throws -> Bool) rethrows -> IndexSet {
        .init(try indices(where: predicate))
    }
    func indexSet(of element: Element) -> [Index] {
        .init(indices(of: element))
    }
}

用法:

let array = [10, 20, 30, 5, 15, 25, 50]
let indices = array.indices { $0.isMultiple(of: 3) }

for index in indices {
    print("element:", array[index], "at:", index)
}

这将打印

元素:30 at:2

元素:15 at:4


let group = ["H","H","E","D","G","D","G","E","D","B","A","B","A","A","G","C","C","H","D","G","H","B","E","F","F","C","E","A","B","C","F","F"]
let indices = group.indices(of: "A")
print(indices) 

这将打印

[10,12,13,27]