在另一个阵列SWIFT 4中循环播放数组和组连续数字的最佳方法?

Mav*_*vro 5 arrays swift

我正在尝试找出使用SWIFT 4循环遍历数字数组的最有效方法,获取任何连续数字的范围并将其添加到新数组中.我可以做标准循环检查,但我相信我可以使用地图过滤器? - 有人能指出我正确的方向吗?

开始:

myNumbersArray:[Int] = [1,2,3,4,10,11,15,20,21,22,23]
Run Code Online (Sandbox Code Playgroud)

通缉结果:

newNumbersArray = [
   [1,2,3,4],
   [10,11],
   [15],
   [20,21,22,23]
]
Run Code Online (Sandbox Code Playgroud)

如果我搞清楚,我会发布我的解决方案......

vad*_*ian 9

我的建议是IndexSet将连续项目存储为范围.

  • 从数组创建索引集.
  • 得到rangeView.
  • 将范围映射到数组.

let myNumbersArray = [1,2,3,4,10,11,15,20,21,22,23]
let indexSet = IndexSet(myNumbersArray)
let rangeView = indexSet.rangeView
let newNumbersArray = rangeView.map { Array($0.indices) }
Run Code Online (Sandbox Code Playgroud)


Leo*_*bus 7

这也适用于负整数:

extension BidirectionalCollection where Element: BinaryInteger, Index == Int {
    var consecutivelyGrouped: [[Element]] { 
        return reduce(into: []) {
            $0.last?.last?.advanced(by: 1) == $1 ? 
            $0[index(before: $0.endIndex)].append($1) :
            $0.append([$1]) 
        }
    }
}
Run Code Online (Sandbox Code Playgroud)
let numbers = [-5,-4,-2,0,1,3,4,10,11,15,20,21,22,23]
let grouped = numbers.consecutivelyGrouped  // [[-5, -4], [-2], [0, 1], [3, 4], [10, 11], [15], [20, 21, 22, 23]]
Run Code Online (Sandbox Code Playgroud)


Lar*_*rme 6

IndexSet虽然根据@vadian使用是一个好主意,但它仅适用于您的情况(连续和正整数),并且使用索引可能不是您的目的。使用类似的对象来实现这一点有点麻烦,但效果很好。

一种可能的方法是使用reduce():

let reduced = myNumbersArray.reduce([[Int]]()) { (current, next) -> [[Int]] in
    var result = current
    //Retrieve the last sequence, check if the current - last item of sequence is 1 to know if they are consecutive or not
    if var lastSequence = result.last, let last = lastSequence.last, next-last == 1 {
        lastSequence.append(next)
        result[result.endIndex-1] = lastSequence
        return result
    } else { //It's not => New array of its own
        result.append([next])
        return result
    }
}
print("reduced: \(reduced)")
Run Code Online (Sandbox Code Playgroud)

输出:

$>reduced: [[1, 2, 3, 4], [10, 11], [15], [20, 21, 22, 23]]
Run Code Online (Sandbox Code Playgroud)

正如@Leo Dabus所建议的,其中reduce(into:):

let reducedInto = myNumbersArray.reduce(into: [[Int]]()) { (result, next) in
    //Retrieve the last sequence, check if the current - last item of sequence is 1
    if var lastSequence = result.last, let last = lastSequence.last, next-last == 1 {
        lastSequence.append(next)
        result[result.endIndex-1] = lastSequence
    } else { //It's not => New array of its own
        result.append([next])
    }
}
print("reducedInto: \(reducedInto)")
Run Code Online (Sandbox Code Playgroud)

输出:

$>reducedInto: [[1, 2, 3, 4], [10, 11], [15], [20, 21, 22, 23]]
Run Code Online (Sandbox Code Playgroud)