繁体   English   中英

FirstIndex:of:对象数组中

[英]FirstIndex:of: in an array of objects

我有这个课:

class ValueTimestamp {
  let value: Double
  let timestamp : Double
  init(value:Double, timestamp:Double) {
    self.value = value
    self.timestamp = timestamp
  }
}

然后我有一个此类的对象数组。

现在,我想扫描该数组并找到具有最小值的ValueTimestamp类的对象。

假设数组有3个元素

  1. element1 (值= 12,时间戳= 2)
  2. element2 (值= 5,时间戳= 3)
  3. element3 (值= 10,时间戳= 4)

let myArray = [element1, element2, element3]

现在我想找到具有最小值的元素。

我以为这会工作

let min = myArray.map({$0.value}).min()
let minIndex = myArray.firstIndex(of: min)

但是第二行给我这个错误

调用中的参数标签不正确(具有“ of:”,预期为“ where:”)

有任何想法吗?

firstIndex:of:查找等于提供的参数的第一个元素。 但是,您并不是在寻找与之相等的元素,而是在寻找一种其value属性相等的元素。 因此,您需要使用where并为此提供功能:

let minIndex = myArray.firstIndex(where: {$0.value == min})

您还可以使您的类符合Comparable并直接在其上调用min

class ValueTimestamp: Comparable {
  let value: Double
  let timestamp : Double
  init(value:Double, timestamp:Double) {
    self.value = value
    self.timestamp = timestamp
  }

  static func == (lhs: ValueTimestamp, rhs: ValueTimestamp) -> Bool {
    return lhs.value == rhs.value
  }
  static func < (lhs: ValueTimestamp, rhs: ValueTimestamp) -> Bool {
    return lhs.value < rhs.value
  }
}

let minObject = myArray.min()

请注意,如果可能有两个具有相同value对象,则可能需要调整功能以确定在这种情况下哪个“较少”。

firstIndex(of: ) Equatable不起作用,因为我认为您的类不符合Equatable

这就是为什么您希望firstIndex(where:)这种情况下使用firstIndex(where:)的原因。

同样在下面的代码中,您没有得到对象,而是得到了值,所以minDouble?类型Double? 不是ValueTimeStamp?

let min = myArray.map({$0.value}).min()

您可以使用where获得以下内容的最小索引:

let minIndex = myArray.firstIndex(where: {$0.value == min})

参考文献:

https://developer.apple.com/documentation/swift/array/2994720-firstindex https://developer.apple.com/documentation/swift/array/2994722-firstindex

根本原因是, firstIndex(of:_)仅在Collection where Element: Equatable定义为Collection where Element: Equatable 您的类型是不平等的,因此直到您使它合规后,您才可以使用此方法。

但是,可以使用Array.enumerated()Array.min(by:_)更好地解决您的问题:

如果只需要该元素,则可以执行以下操作:

 let timestampedValues = [element1, element2, element3]

 let minTimestampedValue = timestampedValues
      .enumerated()
      .min(by: { $0.value })

print(minTimestampedValue as Any)

如果只需要索引,则可以执行以下操作:

let minTimestampedValueIndex = timestampedValues
            .enumerated()
            .min(by: { $0.element.value < $1.element.value })?.offset

print(minTimestampedValueIndex as Any)

如果两者都需要,则可以执行以下操作:

let minTimestampedValuePair = timestampedValues
                .enumerated()
                .min(by: { $0.element.value < $1.element.value })

print(minTimestampedValuePair.offset as Any, minTimestampedValuePair.element as Any)

所有这三个摘要都仅通过数组一次即可获得答案,这使其比“查找最小值,然后找到其索引”方法快两倍。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM