簡體   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