【问题标题】:Swift Array of Ints - Find Index where the Difference to the Previous Element is Greater than 10Swift Array of Ints - 查找与前一个元素的差异大于 10 的索引
【发布时间】:2019-07-04 21:16:30
【问题描述】:

我有以下数组:

let array = [1,3,2,1,4,3,99,3,5,2,1,45]

我想创建一个新数组 - 其中一个元素与前一个元素的差异大于 10,设置为 0。

// [1,3,2,1,4,3,0,3,5,2,1,0]

目前,我正在创建一个具有差异的新数组,然后过滤该数组以找到大于 10 的数组,然后比较这些数组 - 我觉得这一切都过于复杂了。

let diffArray = zip(array.dropFirst(), array).map(-) 
let filteredArray = diffArray.filter {abs($0) > 10}

谢谢!

【问题讨论】:

  • 您不能设置元素的索引。您必须交换两个元素或将其插入到 0 索引处,但其他元素将向右移动。请说明你想做什么。
  • 好的,将编辑问题。
  • 那么第一个号码就可以免票了?
  • 好问题。目前是的。
  • 这个数组会发生什么? [5, 14, 2]

标签: arrays swift filter int


【解决方案1】:

您可以在跟踪前一个元素的同时映射数组:

let a = [1,3,2,1,4,3,99,3,5,2,1,45]

var previous = a.first ?? 0
let b = a.map { elem -> Int in
    defer { previous = elem }
    return elem - previous > 10 ? 0 : elem
}

print(b)
// [1, 3, 2, 1, 4, 3, 0, 3, 5, 2, 1, 0]

【讨论】:

    【解决方案2】:

    应该这样做。不过没什么特别的。

    let array = [1,3,2,1,4,3,99,3,5,2,1,45]
    
    func resetValues(withDifference difference: Int, in array: inout [Int]) {
        for index in array.indices.dropFirst() {
            if abs(array[index - 1] - array[index]) >= 10 {
                array[index] = 0
            }
        }
    }
    
    resetValues(withDifference: 10, in: &array)
    print(array)
    

    【讨论】:

    • 如果以var index = 1开头,检查if index == 0的目的是什么?更简单的是for index in array.indices.dropFirst()。另请注意,您的 resetValues(difference: 10, array: array) 无法编译(参数标签错误,缺少 &)。
    • @MartinR 这是一些我在更改逻辑时忘记删除的旧代码:x 谢谢
    【解决方案3】:

    所以,第一个元素保持原样,而下一个元素被映射。如果与索引为 -1 的初始数组中的元素的差异大于 10,则元素被“替换”为 0

    let array = [1,3,2,1,4,3,99,3,5,2,1,45]
    
    var temp = array
    let mapped = [temp[0]] + temp.dropFirst().enumerated().map {
        let condition = abs(temp[$0.offset] - $0.element) > 10
        if condition { temp[$0.offset + 1] = 0 }
        return condition ? 0 : $0.element
    }
    
    print(mapped) // [1,3,2,1,4,3,0,3,5,2,1,0]
    

    ...如果你不想用替换元素计数,只需删除temp数组的设置元素

    let array = [1,3,2,1,4,3,99,3,5,2,1,45]
    
    let mapped = [array[0]] + array.dropFirst().enumerated().map {
        let condition = abs(array[$0.offset] - $0.element) > 10
        return condition ? 0 : $0.element
    }
    
    print(mapped) // [1,3,2,1,4,3,0,0,5,2,1,0]
    

    或者,例如,如果您只想更改当前数组,可以将此方法添加到 Array 的扩展名 Int

    var array = [1,3,2,1,4,3,99,3,5,2,1,45]
    
    extension Array where Element == Int {
    
        mutating func replace(difference: Int) {
            guard count > 0 else { return }
            self = [self[0]] + self.dropFirst().enumerated().map {
                let condition = abs(self[$0.offset] - $0.element) > difference
                if condition { self[$0.offset + 1] = 0 }
                return condition ? 0 : $0.element
            }
        }
    
    }
    
    array.replace(difference: 10)
    print(array) // [1,3,2,1,4,3,0,3,5,2,1,0]
    

    【讨论】:

    • 我会使用这个答案,因为它提供了两个选项。 Rakesha 在下面的回答也很有效。
    【解决方案4】:

    算法很简单:循环遍历从第二个开始的所有数字,并替换比前一个大 10 的数字。现在,借助 Swift 的数组功能,这可以通过一次函数调用完成:

    let array = [1,3,2,1,4,3,99,3,5,2,1,45]
    
    let filteredNumbers = array.indices.map { i in i > 0 && array[i] - array[i-1] > 10 ? 0 : array[i] }
    

    有点复杂的解决方案,但它避免了按索引访问数组,因此可以应用于任何序列/集合:

    let filteredNumbers = array.reduce(into: (0, [Int]())) { $0.1.append($1-$0.0 > 10 ? 0 : $1); $0.0 = $1 }.1
    

    【讨论】:

      【解决方案5】:

      您的需求陈述和示例之间似乎存在差异。

      “一个元素,它与前一个元素的差异大于10,设置为0”应该导致:

      [1, 3, 2, 1, 4, 3, 0, 0, 5, 2, 1, 0]
      

      但是您的示例结果是 [1,3,2,1,4,3,0,3,5,2,1,0] 这表明差异实际上与前一个元素的“转换”值有关.

      因此,对于所述要求,您可以这样做:

      let filteredArray = array.enumerated().map{ $0 > 0 && abs($1 - array[$0-1]) > 10 ? 0 : $1 }
      

      或者像这样:

      let filteredArray = zip([array[0]]+array,array).map{ abs($0-$1) > 10 ? 0 : $1 }
      

      两者都产生:

      [1, 3, 2, 1, 4, 3, 0, 0, 5, 2, 1, 0]
      

      但是,为了匹配您的示例结果(与之前转换值的差异),您应该这样做:

      let filteredArray = array.dropFirst().reduce([array[0]]){$0 + [abs($1-$0.last!)>10 ? 0 : $1]}
      

      产生:

      [1, 3, 2, 1, 4, 3, 0, 3, 5, 2, 1, 0]
      

      【讨论】:

      • 感谢您澄清这一点,并让我意识到这一点。你完全正确。
      猜你喜欢
      • 2012-11-22
      • 2015-03-08
      • 2012-09-29
      • 2021-07-02
      • 1970-01-01
      • 2016-11-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多