與同一 Array 中的所有其他物件相比,如何確定在 Array 中迭代時實際物件是否滿足特定標準?
讓我用一個例子來解釋我的問題。
假設我們有一個包含 5 個 Person 型別物件的陣列。
data class Person(val name: String, val age: Int)
現在我希望能夠在包含 5 個人的陣列中確定最年長的人,以防該名稱多次出現。
所以在例子中
val pers1 = Person("Jake", 22)
val pers2 = Person("Oliver", 25)
val pers3 = Person("Mark", 35)
val pers4 = Person("John", 35)
val pers5 = Person("Mark", 55)
val persons = arrayOf(pers1, pers2, pers1, pers3, pers4, pers5)
因此,擁有這個陣列我希望能夠在遍歷物件的同時確定我在那一刻正在評估的 Person 是否是整個陣列中具有該名稱的最古老的人,以便我無法對其采取行動...
在偽代碼中類似
for(i in persons.indices){
person with non-unique name AND oldest in this array -> do something
}
uj5u.com熱心網友回復:
一般來說,不可能同時檢查陣列中的所有專案。我們需要對所有專案執行另一次迭代,這使得我們的解決方案非常低效 ( O(n^2))。
但是,這種情況通常可以以更有效的方式實施。例如,您的案例可以通過將串列分組到地圖中來實作:
val maxAgeByName = persons.groupingBy { it.name }
.fold(0) { acc, person -> maxOf(acc, person.age) }
簡單來說,它搜索每個名字的最大年齡。結果是:
{Jake=22, Oliver=25, Mark=55, John=35}
我相信它應該接近O(n).
如果我們不僅需要每個名字中最舊的,而且我們實際上想要遍歷所有的人,那么我們可以從上面的代碼開始,然后遍歷persons:
persons.forEach {
val isOldest = it.age == maxAgeByName[it.name]
}
請注意,在有多個同名同齡人的情況下,我們最終可能會得到多個同名的“最年長”人。
uj5u.com熱心網友回復:
我認為使用 ArrayLists 比使用 Array 更容易,然后這就是您可能想要的:
val pers1 = Person("Jake", 22)
val pers2 = Person("Oliver", 25)
val pers3 = Person("Mark", 35)
val pers4 = Person("John", 35)
val pers5 = Person("Mark", 55)
val persons = arrayListOf(pers1, pers2, pers3, pers4, pers5)
persons.groupBy { it.name }.entries.map { it.value.maxByOrNull { it.age }}.forEach {
//here only the oldest persons of a name come
}
uj5u.com熱心網友回復:
您需要至少進行一次初始傳遞才能Person確定每個名稱中哪個是最舊的 - 如果您只是遍歷陣列,那么當您到達第一個 Mark 時,您將無法知道是否還有另一個更老的 Mark除非你提前檢查(有,哦,嗨,馬克)
與@broot 的回答類似,您可以進行初始傳遞以過濾掉較年輕的重復項,因此您只有一組唯一名稱:
persons.groupBy(Person::name)
.values.mapNotNull { it.maxBy(Person::age) }
然后你可以forEach在它們上運行你的或任何東西。
如果您經常這樣做,您可能希望將其分配給一個可以迭代的變數,而不是每次都將其作為鏈中的第一步。也許Map作為查找表,如果您需要檢查某個特定的人是否是該姓名的最老的人(如@broot 的示例),或者您是否希望能夠輕松更新個人姓名。
但是使用 aList你仍然可以這樣做:
persons.forEach { if (it in oldestPerName) doThing() }
如果您想處理那些重復的 Jakes,這會很有幫助——它們是否都應該算作“最老的”并在它們上面運行處理程式代碼?如果是這樣,根據串列檢查它們oldestPerName將匹配它們兩次。迭代oldestPerName本身只會為每個名稱提供一個匹配項
此外,您可能需要考慮不使用資料類。如果出現另一個Person叫 Mark 并且也是 55 歲的人,就資料類而言,這兩個 Mark 是equal因為它們的資料相同。但是這兩個物件代表了兩個不同的、截然不同的人。如果你把兩個標記放在一個集合中,它應該包含它們兩個,還是只包含一個?如果這很重要,由您決定!在這里很好(并允許您進行簡單的比較),但需要注意
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/345176.html
上一篇:在警告對話框Kotlin中使用服裝按鈕而不是正面和負面按鈕
下一篇:kotlin.UninitializedPropertyAccessException:lateinit屬性layoutManager尚未初始化
