Swift 在数组切片中的 "fromAfter" 调用是什么?

What's Swift's "fromAfter" call in array slices?

Swift 3 有 upTothrough

分别为非包容性、包容性

func prefix(upTo: Int)
Returns a subsequence from the start of the collection up to, but not including, the specified position.

.

func prefix(through: Int)
Returns a subsequence from the start of the collection through the specified position.

另一端有 来自

func suffix(from: Int)
Returns a subsequence from the specified position to the end of the collection.

这似乎是包容性的

远端的非包容呼叫是什么?

    // sum the numbers before, and after, an index i...

    let lo = A.prefix(upTo: i).reduce(0,+)    // means noninclusive
    let hi = A.suffix(from: i+1).reduce(0,+)  // 'from' seems to mean inclusive

不知道叫什么?不得不用 +1 来写真是太糟糕了。

对于标准库中的 Collection 类型,目前没有非包容性的 suffix 方法,但是对于这个用例,您可以通过将 suffix(from:)dropFirst(_:)(恕我直言,比 from: idx+1 更能体现意图),例如

extension Collection where SubSequence == SubSequence.SubSequence {
    public func suffix(after start: Index) -> SubSequence {
        return suffix(from: start).dropFirst(1)
    }
}

应用于您的示例(分别对给定分区号(或索引)前后的数字求和,不包括分区号):

/* in this example, invalid indices will yield a full-array sum into
   lo or hi, depending on high or low index out of bounds, respectively */
func splitSum(of arr: [Int], at: Int) -> (Int, Int) {
    guard at < arr.count else { return (arr.reduce(0, +), 0) }
    guard at >= 0 else { return (0, arr.reduce(0, +)) }

    let lo = arr.prefix(upTo: at).reduce(0, +)
    let hi = arr.suffix(after: at).reduce(0, +)

    return (lo, hi)
}

// example usage
let arr = [Int](repeating: 1, count: 10)
print(splitSum(of: arr, at: 4)) // (4, 5)

离开非包容性 suffix 方法的主题,拆分和计算的另一种方法是对 Collection 类型使用 the split(...) methods 之一:

func splitSum(of arr: [Int], at: Int) -> (Int, Int) {
    guard at < arr.count else { return (arr.reduce(0, +), 0) }
    guard at >= 0 else { return (0, arr.reduce(0, +)) }

    let sums = arr.enumerated()
        .split (omittingEmptySubsequences: false) { [=12=].0 == at }
        .map { [=12=].reduce(0) { [=12=] + .1 } }

    guard let lo = sums.first, let hi = sums.last else { fatalError() }

    return (lo, hi)
}

// example: same as above

我认为 split 版本有点冗长,而且在显示代码意图方面语义上也较差。