You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift中按相邻元素差值分割数组的实现及Combine框架疑问

Swift 数组按相邻元素差值分割的实现方案

问题描述

给定已排序的整数数组:

let array = [1, 3, 4, 7, 8, 12]

需在相邻元素差值超过2的位置进行分割,生成子数组,最终输出:

[ [1,3,4], [7,8], [12] ]

原生Swift优雅实现

利用reduce(into:)方法可简洁完成需求,通过累积子数组的方式逐步构建结果:

let array = [1, 3, 4, 7, 8, 12]
let result = array.reduce(into: [[Int]]()) { accumulator, current in
    guard let lastSubarray = accumulator.last else {
        accumulator.append([current])
        return
    }
    // 判断当前元素与最后一个子数组末尾元素的差值
    if current - lastSubarray.last! <= 2 {
        accumulator[accumulator.count - 1].append(current)
    } else {
        accumulator.append([current])
    }
}
print(result) // 输出 [[1, 3, 4], [7, 8], [12]]

该方案仅遍历数组一次,时间复杂度为O(n),逻辑直观且符合Swift函数式编程风格。

Combine框架实现

Combine没有直接提供完成该需求的内置运算符,但可通过组合现有运算符实现:

import Combine

let array = [1, 3, 4, 7, 8, 12]
var cancellables = Set<AnyCancellable>()

array.publisher
    // 将当前元素与下一个元素配对
    .zip(array.publisher.dropFirst())
    // 累积构建子数组
    .scan([[array.first!]]) { accumulator, pair in
        let (prev, current) = pair
        var accum = accumulator
        if current - prev <= 2 {
            accum[accum.count - 1].append(current)
        } else {
            accum.append([current])
        }
        return accum
    }
    // 取最终的累积结果
    .last()
    .sink(receiveValue: { result in
        print(result!) // 输出 [[1, 3, 4], [7, 8], [12]]
    })
    .store(in: &cancellables)

核心思路是通过zip关联相邻元素,再用scan累积生成子数组,最后通过last获取最终结果。如果是处理异步数据流,这种方式更贴合Combine的响应式编程模式。

内容的提问来源于stack exchange,提问作者koira

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 20:24:56