我正在 Kotlin/Java 中尋找一種最有效的方法List來按一定百分比過濾掉過濾元素,并且刪除過濾后的元素將以統一的方式應用于整個集合(即 - 要刪除的元素跨越整個集合均勻收集);例如將以下內容過濾 50%[0,1,2,3,4,5,6,7,8,9] = [0,2,4,6,8]將以下內容過濾 10%[1,100,1000,10000] = [1,100,10000]我想出了以下 Kotlin 擴展函數,它在百分比 < 50% 且集合很大時效果很好,但當集合 > 50% 時,這種方法就失敗了,因為它只處理整數除法。private fun <E> List<E>.filterDownBy(perc: Int): List<E> {val distro = this.size / ((perc * this.size) / 100)if (perc == 0 || distro >= this.size) return thisreturn this.filterIndexed { index, _ -> (index % distro) != 0 }有沒有更好的方法來做到這一點并且當百分比大于 50% 時也能工作?
1 回答

慕尼黑8549860
TA貢獻1818條經驗 獲得超11個贊
我認為標準庫中沒有多少有用的東西,但我想出了這種“手動”方法:
fun <T> List<T>.takeProportion(prop: Double): List<T> {
if (prop < 0 || prop > 1)
throw IllegalArgumentException("prop ($prop) must be between 0 and 1")
val result = ArrayList<T>()
var tally = 0.5
for (i in this) {
tally += prop
if (tally >= 1.0) {
result += i
tally -= 1
}
}
return result
}
它使用一種錯誤擴散的方式來確保值在列表中均勻地取值,并使用浮點數以便它平滑地處理從 0.0(給出一個空列表)到 1.0(取每個元素)的任何比例。
(可能有一種方法只使用整數運算來完成它,但使用浮點數可能更容易編碼和理解。)
(您可能可以通過使用 使它看起來更實用filter(),但這并不合適,因為 lambda 必須使用和更新外部狀態。)
添加回答
舉報
0/150
提交
取消