为了账号安全,请及时绑定邮箱和手机立即绑定

按一定百分比均匀过滤列表 - Kotlin/Java

按一定百分比均匀过滤列表 - Kotlin/Java

POPMUISE 2022-12-28 13:57:50
我正在 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 必须使用和更新外部状态。)


查看完整回答
反对 回复 2022-12-28
  • 1 回答
  • 0 关注
  • 101 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信