过滤Swift数组并给出指数(不是值)

时间:2017-09-20 13:56:46

标签: arrays swift functional-programming

我需要按照元素的某些条件过滤数组,但我需要获取通过测试的元素的 indices 元素本身。

例如:给定一个Bool数组,我想将其转换为Int数组,该数组仅包含true的原始数组元素的索引。

可以 执行此操作:

// INPUT array:
let flags = [true, false, true, false]

// OUTPUT array:
var trueIndices = [Int]()

for (index, value) in flags.enumerated() where value == true {
    trueIndices.append(index)
}

...但它并非“swifty”

有更优雅的方式吗?类似于filter()的东西,但返回索引而不是元素。

3 个答案:

答案 0 :(得分:4)

您可以直接filter指数

let flags = [true, false, true, false]    
let trueIndices = flags.indices.filter{ flags[$0] }

let falseIndices = flags.indices.filter{ !flags[$0] }

答案 1 :(得分:2)

不确定" swiftier" 多少,但您也可以使用连续filtermap操作,或只使用一个{{} 1}}而不是。当然,您可以声明数组是不可变的,并且您不必编写任何显式循环,这两种循环通常被认为是比当前更有效的方法。

flatMap

输出:

  

[0,2]

使用单个let trueIndices = flags.enumerated().filter{$0.element}.map{$0.offset} print(trueIndices)

flatMap

答案 2 :(得分:0)

这就是我要做的。它可以推广到序列,甚至是下标不是O(1)的集合。

let indicesOfTrue = Array(flags.enumerated().lazy.filter{ $0.element }.map{ $0.offset })