分配数组值,使最大值为1,最小值为0

时间:2015-08-23 16:54:14

标签: ios arrays swift

我认为这必须是一个基本的数学运算,但我真的无法弄明白。我需要根据给定数组的值得到介于0和1之间的值数组。因此,例如,如果我们有一个初始数组[24, 128, 52],结果数组应为[0, 1, 0.5]。最大值和最小值应始终分别为1和0,其余值应按比例在它们之间。

如何在Swift中执行此操作?

3 个答案:

答案 0 :(得分:4)

从数组开始:

let sourceArray = [24.0, 128.0, 52.0]

存储最小和最大元素:

let min = minElement(sourceArray) // 24.0
let max = maxElement(sourceArray) // 128.0

规范化每个元素并将结果映射到新数组:

let results = sourceArray.map { ($0 - min) / (max - min) }

results是:

[0, 1, 0.2692307692307692]

你指定了你想要的[0, 1, 0.5],但我认为这是错的,因为你说“其余的应该在它们之间成比例”。输入[24.0, 128.0, 76.0]会输出[0, 1, 0.5]

注意:源数组不能是[Int],否则地图操作会将结果四舍五入为1或0.如果您需要使用[Int]将必须转换map操作中的每个元素。

答案 1 :(得分:1)

在Swift 5中使用:

let min = sourceArray.min()
let max = sourceArray.max()
// will produce optionals! Unwrap them if you are sure they won't be nil
let results = sourceArray.map { ($0 - min!) / (max! - min!) }

答案 2 :(得分:0)

let array: [Double] = [24, 128, 52]
array.map { [range = ClosedRange(encompassing: array)!] in
  range.normalize($0)!
}
public extension ClosedRange {
  /// A range whose bounds are the extremes of a given sequence.
  ///
  /// - Returns: `nil` if the sequence is empty.
  init?<Bounds: Sequence>(encompassing bounds: Bounds)
  where Bounds.Element == Bound {
    guard let initialRange = ( bounds.first.map { $0...$0 } )
    else { return nil }

    self = bounds.dropFirst().reduce(into: initialRange) { range, bound in
      if bound < range.lowerBound {
        range = bound...range.upperBound
      } else if bound > range.upperBound {
        range = range.lowerBound...bound
      }
    }
  }
}

public extension ClosedRange where Bound: AdditiveArithmetic {
  /// `upperBound - lowerBound`
  var magnitude: Bound { upperBound - lowerBound }
}

public extension ClosedRange where Bound: FloatingPoint {
  /// A value whose unit is the `magnitude` of this range,
  /// and whose origin is `lowerBound`.
  ///
  /// - Note: Not clamped between 0 and 1.
  ///
  /// - Returns: `nil` when the range has zero magnitude.
  func normalize(_ bound: Bound) -> Bound? {
    try? (bound - lowerBound) ÷ magnitude
  }
infix operator ÷: MultiplicationPrecedence

public extension FloatingPoint {
  /// - Throws: `DivisionByZeroError<Self>`
  static func ÷ (numerator: Self, denominator: Self) throws -> Self {
    guard denominator != 0
    else { throw DivisionByZeroError(numerator: numerator) }

    return numerator / denominator
  }
}
public extension Sequence {
  /// The first element of the sequence.
  /// - Note: `nil` if the sequence is empty.
  var first: Element? {
    var iterator = makeIterator()
    return iterator.next()
  }
}
// Division isn't actually found in `Numeric`,
// but it does seem to be found in all the important protocols that inherit from it.
public struct DivisionByZeroError<Numerator: Swift.Numeric>: Error {
  public let numerator: Numerator

  public init(numerator: Numerator) {
    self.numerator = numerator
  }
}