【问题标题】:Find lowest value and its index number in swift快速查找最小值及其索引号
【发布时间】:2021-03-10 22:07:57
【问题描述】:

我有以下数组 var numbers = [2, 4, 4, 2, 3, 1]

顺序很重要,我需要找到最小值的索引。 那么如何找到最低价值指数呢?我需要能够调用 numbers[lowestValueIndex] 并获得正确的值

感谢任何帮助

【问题讨论】:

  • 您最好编辑问题以向我们展示您的尝试。我们不是来为您解决编程测试的。但是,如果您向我们展示您的善意尝试,我们很乐意提供帮助...
  • 我尝试对数组进行排序并找到最小值。但是,如果我这样做,我可以使用numbers.first,但我的顺序是混乱的。
  • 我没有看到完全匹配,但有很多类似的问题(最小值或最大值相似)stackoverflow.com/search?q=%5Bswift%5D++max+value+and+index
  • @LeoDabus 我没有投反对票,但可能是因为它可能被解释为没有回答问题。问题是“获取最小值的索引”,而不是“获取最小值”。当一个编程测试题用这样的措辞时,他们通常会寻找一些非常具体的东西。
  • @Rob 实际上问题要求索引,因此它需要所有索引而不仅仅是第一个索引。无论如何,我也可以在我的帖子中包含所有索引

标签: ios arrays swift


【解决方案1】:

我一直认为在这种情况下扩展数组提供了一个更简洁的调用站点。

extension Array where Element == Int {
   func lowest() -> (value: Element, positions:[Index])? {
      guard !isEmpty else {return nil }  //you may wish to throw an error rather than return nil
      return indices.reduce( (value: Element.max, positions: [Index]() ) ) {
         switch self[$1] {
            case let x where x < $0.value: return (value: self[$1], positions:[$1])
            case let x where x > $0.value: return $0
            default: return ($0.value, $0.positions + [$1])
         }
      }
   }
}

可以使用 _ 或模式匹配来简化 switch 语句,但我觉得这种更冗长的方法更容易理解。与可选的返回类型相比,抛出错误或返回 Result 可能是处理空数组更好的方法,但会增加答案的膨胀,如果愿意,可以稍后由 OP 添加。

[2,3,6,1,7,3,1,6,7].lowest() // (value: 1, positions: [3, 6])

[2,3,6,6,7,3,1,6,7].lowest() // (value: 1, positions: [6])

[Int]().lowest() // nil

【讨论】:

    【解决方案2】:

    可以使用min(by:)数组方法;诀窍是对数组的indices 属性进行操作,以便您可以返回相关索引:

    func minIndex(someArray: [Int]) -> Int? {
        return someArray.indices.min { someArray[$0] < someArray[$1] }
    }
    

    如果数组为空,函数会返回nil

    为简单起见,我将其显示为一个函数。当然,如果您愿意,可以将其作为 Array 的扩展来实现。

    【讨论】:

    • 为什么不只是 [2, 4, 4, 2, 3, 1].enumerated().min { $0.element &lt; $1.element } 而不是索引?
    • 你可以这样做。
    【解决方案3】:

    如果您只需要一个值,其他答案将处理如何处理。否则……

    let numbers = [2, 4, 4, 2, 3, 1, 1]
    
    // [(offset 5, element 1), (offset 6, element 1)]
    numbers.min().map { min in
      numbers.enumerated().filter { $0.element == min }
    }
    

    如果您需要对数组进行排序以供进一步使用,则前缀比过滤器更好。

    let sorted =
      [2, 4, 4, 2, 3, 1, 1]
      .enumerated()
      .sorted(by: \.element)
    
    sorted.first.map { first in
      sorted.prefix { $0.element == first.element }
    }
    
    public extension Sequence {
      /// Sorted by a common `Comparable` value.
      func sorted<Comparable: Swift.Comparable>(
        by comparable: (Element) throws -> Comparable
      ) rethrows -> [Element] {
        try sorted(by: comparable, <)
      }
    
      /// Sorted by a common `Comparable` value, and sorting closure.
      func sorted<Comparable: Swift.Comparable>(
        by comparable: (Element) throws -> Comparable,
        _ areInIncreasingOrder: (Comparable, Comparable) throws -> Bool
      ) rethrows -> [Element] {
        try sorted {
          try areInIncreasingOrder(comparable($0), comparable($1))
        }
      }
    }
    

    【讨论】:

    • 不,(&lt;) 实际上不起作用,因为您需要将try 放在所有调用的前面。重载是解决这个问题的唯一方法。
    【解决方案4】:

    首先你需要定义输入数组中重复值的行为。 完成后,试试这个:

      func returnLowestValueIndex(array: [Int]) -> Int? {
          guard !array.isEmpty else { return nil }
      
          var lowestValueIndex: Int = 0
          for (index, value) in array.enumerated() {
          if value < array[lowestValueIndex] {
             lowestValueIndex = index
          }
      
        return lowestValueIndex
      }
    
      var numbers = [2, 4, 4, 2, 3, 10]
      returnLowestValueIndex(array: numbers)
    

    【讨论】:

      猜你喜欢
      • 2018-01-29
      • 1970-01-01
      • 1970-01-01
      • 2016-11-05
      • 2020-09-12
      • 2016-02-09
      • 2016-02-24
      • 2017-05-22
      • 1970-01-01
      相关资源
      最近更新 更多