What's Swift's “fromAfter” call in array slices?

╄→гoц情女王★ 提交于 2019-12-23 23:17:28

问题


Swift 3 has upTo and through

which are noninclusive, inclusive respectively

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.

for the other end it has from

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

which seems to be inclusive

What's the non-inclusive call at the far end??

    // 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

what's the call I don't know? It sucks to have to write from with +1.


回答1:


There is currently no non-inclusive suffix method for for Collection types in the stdlib, but for this use case, you can readily implement your own by combining suffix(from:) with dropFirst(_:) (which, imho, better shows intent than from: idx+1), e.g.

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

Applied to your example (separately sum numbers before and after a given partitioning number (or, index of), not including the partitioning one):

/* 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)

Leaving the subject of a non-inclusive suffix method, an alternative approach to your split sum calculation would be to use one of the split(...) methods for Collection types:

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) { $0.0 == at }
        .map { $0.reduce(0) { $0 + $1.1 } }

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

    return (lo, hi)
}

// example: same as above

I believe the split version is a bit more verbose, however, and also semantically poorer at showing the intent of the code.



来源:https://stackoverflow.com/questions/40312252/whats-swifts-fromafter-call-in-array-slices

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!