【问题标题】:What's Swift's "fromAfter" call in array slices?Swift 在数组切片中的“fromAfter”调用是什么?
【发布时间】:2016-10-28 19:46:53
【问题描述】:

Swift 3 有 upTothrough

分别是非包容、包容

func 前缀(upTo: Int)
返回从集合开始直到(但不包括)指定位置的子序列。

.

func 前缀(通过:Int)
返回从集合开始指定位置的子序列。

另一端有 来自

func 后缀(来自:Int)
返回从指定位置到集合末尾的子序列。

这似乎是包容性的

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

    // 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 来写真是糟透了。

【问题讨论】:

  • 非包含签名不在 Swift 标准库参考中,suffix(_:)suffix(from: ) 参考都显示了包含示例,因此在此版本中不可用。我也没有看到任何引用非包含后缀的讨论,因此不太可能很快推出。
  • 啊-很棒的信息。也许应该将其粘贴为决定性的答案,@gelliott181?
  • 我是一个短暂的 swift 用户,所以我通常更愿意将实际答案留给可以提供详细信息的人,就像 @dfri 所做的那样。

标签: swift3 slice


【解决方案1】:

目前在 stdlib 中没有针对 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 方法的主题,您的拆分和计算的另一种方法是使用the split(...) methods 中的一个Collection 类型:

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

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

【讨论】:

  • 壮观。我不得不承认我不明白 where SubSequence == SubSequence.SubSequence,我也无法在 doco 或任何教程中找到它的解释。也许你可以慷慨地添加一行解释它,供凡人阅读;)Tak!
  • @JoeBlow 这并不像乍一看那样棘手。 suffix(after:) 方法的返回类型是Self.SubSequence。现在,对于某个给定的序列,比如seq,现有的suffix(from:) 方法(我们在方法的return 子句中调用)返回。本身,一个Self.SubSequence 类型的实例(其中Selfseq 的类型:某种符合Sequence 的类型)。所以如果return 语句看起来像return suffix(from: start),我们就不需要where SubSequence == SubSequence.SubSequence 规范,因为return 子句的类型匹配......
  • ...我们在suffix(after:)方法中指定的返回类型,即Self.SubSequence。然而,在我们的例子中,我们将dropFirst(_:) 方法应用于suffix(from:) 调用返回的Self.SubSequence 实例dropFirst(_:) 的返回类型也是Self.SubSequence,其中Self 是调用者的类型。因为在我们的例子中,调用者是Self.SubSequenceSelfseq 的类型),所以链式调用suffix(from: start).dropFirst(1)类型Self.SubSequence.SubSequence。由于方法的返回类型是Self.SubSequence,...
  • ... 我们需要确定Self.SubSequence 确实与Self.SubSequence.SubSequence 是同一类型,因此在扩展的“签名”中指定where SubSequence == SubSequence.SubSequence。所以最终归结为确定我们返回了由suffix(after:) 的方法签名指定的正确类型。希望这可以解决问题!
  • 这需要考虑一下:O
猜你喜欢
  • 2014-07-27
  • 2015-08-22
  • 2017-06-19
  • 1970-01-01
  • 2021-10-28
  • 1970-01-01
  • 1970-01-01
  • 2011-01-26
  • 1970-01-01
相关资源
最近更新 更多