【问题标题】:Remove every nth element from swift array从 swift 数组中删除每个第 n 个元素
【发布时间】:2019-03-07 19:40:07
【问题描述】:

有没有一种简单的方法可以从 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]

【问题讨论】:

    标签: arrays swift


    【解决方案1】:
    // swift 4.1:
    thisArray.enumerated().compactMap { index, element in index % 3 == 2 ? nil : element }
    
    • 使用.enumerated() 附加索引
    • 然后使用.compactMap 通过返回nil 过滤掉索引为2、5、8...的项目,并通过仅返回element 去除其余索引。

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

    (如果您坚持使用 Swift 2,请使用 .enumerate() 而不是 .enumerated()。)

    【讨论】:

    • @CameronLowellPalmer 谢谢,改为.compactMap()
    【解决方案2】:

    由于已经发布了函数式解决方案,我在这里使用了一种老式的方法

    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】:

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

    0 1 2 3 4 5 6 7 8 ... 旧数组索引 | | / / / / | | | | // | | | | // | | / / / / 0 1 2 3 4 5 6 ... 新数组索引

    代码:

    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

    【讨论】:

      【解决方案4】:

      实现此目的的一种方法是使用flatMap,它会从数组中删除 nil,因此我们只需为要删除的索引返回 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-1th 元素。

      可以通过 strides 实现更实用的解决方案:

      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] }
      

      【讨论】:

        猜你喜欢
        • 2011-07-14
        • 1970-01-01
        • 1970-01-01
        • 2015-04-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-27
        相关资源
        最近更新 更多