[英]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個元素
element1
(值= 12,時間戳= 2) element2
(值= 5,時間戳= 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:)
的原因。
同樣在下面的代碼中,您沒有得到對象,而是得到了值,所以min
是Double?
類型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.