从swift数组中删除每个第n个元素

时间:2016-08-28 21:39:09

标签: arrays swift

是否有一种简单的方法可以从swift数组中删除每个第n个元素。例如,在下面的数组中:

thisArray = [2.0, 4.0, 3.0, 1.0, 4.5, 3.3, 1.2, 3.6, 10.3, 4.4, 2.0, 13.0]

如果n = 3并且从第一个元素开始计数想要返回:

returnThis = [2.0, 4.0, 1.0, 4.5, 1.2, 3.6, 4.4, 2.0]

4 个答案:

答案 0 :(得分:4)

// swift 4.1:
thisArray.enumerated().compactMap { index, element in index % 3 == 2 ? nil : element }
  • 使用.enumerated()附加索引
  • 然后使用.compactMap通过返回nil来过滤掉索引2,5,8等处的项目,并通过仅返回element来删除其余的索引。< / LI>

(如果您使用的是Swift 4.0或更低版本,请使用.flatMap代替.compactMap.compactMap方法在Swift 4.1中引入SE-0187

(如果您遇到Swift 2,请使用.enumerate()代替.enumerated()。)

答案 1 :(得分:2)

您可以直接从旧计算新数组 数组通过调整指数。对于n=3,它看起来像这样:

    0 1 2 3 4 5 6 7 8 ...    old array index
    | |   / /   / /
    | |  | |   / /
    | |  | |  / /
    | |  / / / / 
    0 1 2 3 4 5 6 ...        new array index

代码:

let thisArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
let n = 3

let newCount = thisArray.count - thisArray.count/n
let newArray = (0..<newCount).map { thisArray[$0 + $0/(n - 1)] }

print(newArray) // [1, 2, 4, 5, 7, 8, 10]

从旧数组中获取n-1个元素后 你必须跳过一个元素。这可以通过添加$0/(n - 1)来实现 到地图闭包中的(新)数组索引$0

答案 2 :(得分:1)

由于功能样式解决方案已经发布,我在这里使用的是一种古老的方式方法

let nums = [2.0, 4.0, 3.0, 1.0, 4.5, 3.3, 1.2, 3.6, 10.3, 4.4, 2.0, 13.0]

var filteredNums = [Double]()
for elm in nums.enumerate() where elm.index % 3 != 2 {
    filteredNums.append(elm.element)
}

答案 3 :(得分:0)

实现这一目标的一种方法是使用flatMap除了其他功能之外,它会从数组中删除nils,因此我们只需返回nil作为我们要删除的索引:

let n = 3
let arr = [2.0, 4.0, 3.0, 1.0, 4.5, 3.3, 1.2, 3.6, 10.3, 4.4, 2.0, 13.0]
let filteredArr = arr.enumerate().flatMap {$0.index % n == n - 1 ? nil : $0.element }

对于swift 3:

let filteredArr = thisArray.enumerated().flatMap {$0.offset % n == n - 1 ? nil : $0.element }

一般来说,您忽略数组的N-1元素。

通过跨步可以实现更具功能性的解决方案:

let filteredArr = (n-1).stride(to: arr.count, by: n).flatMap { arr[($0-n+1)..<$0] }

这里的方法是获取将被过滤掉的索引,然后在两个连续过滤的索引之间连接切片。

或另一种方法,通过reduce,实际上是filter / map / flatMap减少到:

let filteredArr = arr.enumerate().reduce([]) { $1.0 % n == n - 1 ? $0 : $0 + [$1.1] }
// or, both produce the same results
let filteredArr = arr.reduce((0,[])) { ($0.0 + 1, $0.0 % n == n - 1 ? $0.1 : $0.1 + [$1]) }.1

而不是最后一个数学方法:获取数组中的索引集,减去我们不想要的索引,从排序的结果索引构建结果数组:

let filteredArr = Set(0..<arr.count).subtract((n-1).stride(to: arr.count, by: n)).sort(<).map { arr[$0] }