swift 将数组拆分成对

dsf9zpds  于 12个月前  发布在  Swift
关注(0)|答案(4)|浏览(121)

我试图将数组拆分成对。我可以拆分成连续的对,但我想拆分成包括结果中提到的先前值的对
逻辑分裂连续对,我试过了。

extension Array {
func chunks(_ chunkSize: Int) -> [[Element]] {
    return stride(from: 0, to: self.count, by: chunkSize).map {
        Array(self[$0..<Swift.min($0 + chunkSize, self.count)])
    }
}

字符串
阵法:

["1", "2", "3", "4", "5", "6", "7", "8", "9"]


结果如下:

[["1", "2"], ["2", "3"], ["3", "4"], ["4", "5"], ["6", "7"], ["7", "8"], ["8", "9"]]

fhg3lkii

fhg3lkii1#

不如这样吧:

let a = [ 1, 2, 3, 4, 5, 6, 7, 8, 9]

let pairs = Array(zip(a, a.dropFirst())).map {[$0.0, $0.1] }

print(pairs)

字符串
用于输出
[[1、2]、[2、3]、[3、4]、[4、5]、[5、6]、[6、7]、[7、8]、[8、9]]

编辑:

如果你想要任意的块大小,你可以这样写扩展:

extension Array {
    func chunks(_ chunkSize: Int, includePartialChunk: Bool = true) -> [[Element]] {
        var indexes = Array<Int>(stride(from: 0, to: count, by: chunkSize - 1))
        if includePartialChunk,
           let last = indexes.last,
           last < count - 1 {
            indexes.append(count-1)
        }
        return zip(indexes, indexes.dropFirst()).map {Array(self[$0.0...$0.1])}
    }
}


使用参数includePartialChunk告诉函数,当数组大小不是块大小的偶数倍时,是否要在末尾包含“部分块”。(默认值)它返回最后一个块,该块小于chunkSize,但位于数组的末尾。如果为false,则只返回完整大小的块,但会在末尾跳过不适合完整大小块的数组元素。
(我必须研究Leo的UnfoldSequence版本,看看我的代码是否能适应它。

aemubtdh

aemubtdh2#

这不是对这个问题的直接回答,但序列的元素应该是惰性计算的。你应该使用Swift UnfoldSequence类型,如下所示:

extension Collection {
    var unfoldedNeighbors: UnfoldSequence<SubSequence,Index> {
        sequence(state: startIndex) { start in
            guard start < endIndex else { return nil }
            guard let end = index(start, offsetBy: 2, limitedBy: endIndex) else {
                return nil
            }
            defer { formIndex(after: &start) }
            return self[start..<end]
        }
    }
    var neighborsSubsequences: [SubSequence] {
        .init(unfoldedNeighbors)
    }
    var neighborsArrays: [[Element]] {
        unfoldedNeighbors.map([Element].init)
    }
}

字符串
使用方法:

let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]
for neighbors in numbers.unfoldedNeighbors {
    print(neighbors)
}


如果你需要控制每个子序列的元素数量,并且它是否包括尾部:

extension Collection {
    func unfoldedNeighbors(limitedTo length: Int, includesTail: Bool = false) -> UnfoldSequence<SubSequence,Index> {
        sequence(state: startIndex) { start in
            guard start < endIndex else { return nil }
            guard let end = index(start, offsetBy: length, limitedBy: endIndex) else {
                if includesTail {
                    defer { formIndex(&start, offsetBy: length-1, limitedBy: endIndex) }
                    return self[start...]
                }
                return nil
            }
            defer { formIndex(&start, offsetBy: length-1, limitedBy: endIndex) }
            return self[start..<end]
        }
    }
    func neighborsSequences(limitedTo length: Int, includesTail: Bool = false) -> [SubSequence] {
        .init(unfoldedNeighbors(limitedTo: length, includesTail: includesTail))
    }
    func neighborsArrays(limitedTo length: Int, includesTail: Bool = false) -> [[Element]] {
        unfoldedNeighbors(limitedTo: length, includesTail: includesTail).map([Element].init)
    }
}


使用方法:

let numbers = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
for neighbors in numbers.unfoldedNeighbors(limitedTo: 3, includesTail: true) {
    print(neighbors)
}


这将打印:
[第1、2、3页]
[3、4、5]
[5、6、7]
[第7、8、9页]
[9、10]

let neighborsSequences = a.neighborsSequences(limitedTo: 3, includesTail: true)  // [[1, 2, 3], [3, 4, 5], [5, 6, 7], [7, 8, 9], [9, 10]] of type [Array<Int>.SubSequence]
let neighborsArrays = a.neighborsArrays(limitedTo: 3, includesTail: true)        // [[1, 2, 3], [3, 4, 5], [5, 6, 7], [7, 8, 9], [9, 10]] of type [[Int]]

wb1gzix0

wb1gzix03#

这个操作的代号是windows。它完全按照你的要求执行,计数2...

import Algorithms

Array(["1", "2", "3", "4", "5", "6", "7", "8", "9"].windows(ofCount: 2))

字符串
……但还不清楚它是否能满足你对其他罪名的要求。

7dl7o3gd

7dl7o3gd4#

至少,它很容易阅读和O(n)复杂度。

extension Int {
    var nextIndex: Int {
        self + 1
    }
}

extension Array {
    var splitedByCouples: [[Element]] {
        guard !self.isEmpty else {
            return []
        }
        
        let couplesMaxCount = self.count / 2
        var source = self
        var couples: [[Element]] = []
        
        while couples.count < couplesMaxCount {
            let couple = [source[.zero], source[.zero.nextIndex]]
            couples.append(couple)
            source.removeSubrange(0...1)
        }
        if source.count == 1 {
            couples.append([source.last!])
        }
        return couples
    }
}

字符串
用法如下:

// prints "[[1, 2], [3, 4], [5, 6], [7]]"
print([1,2,3,4,5,6,7].splitedByCouples)

// prints "[]"
print(Array<String>().splitedByCouples)

// prints "[[0.0]]"
print([Double.zero].splitedByCouples)

// prints "[[true, false], [true, false]]"
print([true, false, true, false].splitedByCouples)

相关问题