Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Kotlin 计算所有列表元素的总和,直到满足条件为止_Kotlin - Fatal编程技术网

Kotlin 计算所有列表元素的总和,直到满足条件为止

Kotlin 计算所有列表元素的总和,直到满足条件为止,kotlin,Kotlin,我面临以下问题:我有一个对象列表。让它成为类测试的对象: data class Test( var status: String, // Can be EXPIRED, WAIT var amount: Float ) 数组被排序后,在开始和之后都有状态为WAIT的对象,状态为EXPIRED。我需要计算状态为过期的所有元素(如果存在)的总和,并将类型为等待的第一个对象(如果存在)的总和相加。现在我有以下代码: private fun getRestructuringAmoun

我面临以下问题:我有一个对象列表。让它成为类测试的对象:

data class Test(
    var status: String, // Can be EXPIRED, WAIT
    var amount: Float
)
数组被排序后,在开始和之后都有状态为
WAIT
的对象,状态为
EXPIRED
。我需要计算状态为
过期的所有元素(如果存在)的总和,并将类型为
等待的第一个对象(如果存在)的总和相加。现在我有以下代码:

 private fun getRestructuringAmountToPay(): Float {
        var i = 0
        var sum = 0F
        list?.forEachIndexed { iter, el ->
            if (el.status != RestructingItemStatus.WAIT) {
                i = iter
                sum += el.amount ?: 0F
            }
        }
        if (i + 1 < (list?.size ?: 0)) {
            sum += list?.get(i+1)?.amount ?: 0F
        }
        return sum
    }
private fun getRestructuringAmountToPay():Float{
变量i=0
var总和=0F
列表?.forachinedexed{iter,el->
if(el.status!=重构项状态。等待){
i=国际热核实验堆
总和+=el.金额?:0F
}
}
如果(i+1<(列表?.size?:0)){
总和+=列表?获取(i+1)?。金额?:0F
}
回报金额
}

但是有没有办法改进这段代码,让它变得漂亮呢?提前感谢您的帮助

我会走老路,使用
for
循环,而不是
forachined
方法,这样当我点击第一个
等待
条目时,我就可以
打破
循环。我会这样做:

private fun getRestructuringAmountToPay(): Float {
    var sum = 0F
    for (el in list) {
        if (el.status == RestructingItemStatus.WAIT) {
            el.amount += sum
            break
        }
        else {
            sum += el.amount
        }
    }
    return sum
}

这是一种简单而优雅的方法,可以在不需要对列表进行任何额外迭代的情况下完成最少量的工作。如果你是“我必须把所有东西塞进尽可能少的代码行”中的一员,那么肯定有更复杂、更紧凑的方法可以做到这一点。我常常难以理解此类解决方案的实际优势。

当您说要查找列表中状态为
“EXPIRED”
的所有元素时,我想到了
filter()
。当你说要求和时,我想到了
sumBy()
。当您说要将该数字添加到列表中状态为“WAIT”
的第一个元素时,我想到了
first()

我们实际上不能使用正常的
sumBy()
函数,因为
Test.amount
属于
Float
类型,所以我们可以做的最接近的事情就是使用
sumByDouble()
并将
amount
转换为
Double

val expiredSum = list.filter { it.status == "EXPIRED" }.sumByDouble { it.amount.toDouble() }
val result = list.first { it.status == "WAIT" }.amount + expiredSum
如果不希望在没有状态为“WAIT”的元素时引发异常,请改用
firstOrNull()

val expiredSum = list.filter { it.status == "EXPIRED" }.sumByDouble { it.amount.toDouble() }
val initialValue = list.firstOrNull { it.status == "WAIT" }?.amount ?: 0F
val result = initialValue + expiredSum

我不确定我是否理解您的解决方案,但我分别理解您的目标:

    var sum = list.filter { it.status == "EXPIRED" }.sumByDouble { it.amount.toDouble() }
    list.firstOrNull{ it.status == "WAIT" }?.let { sum+=it.amount}

    println(sum)

由于您的列表已排序,并且
EXPIRED
项目位于第一位,因此您可以使用
firstOrNull
要查找状态为等待的第一项,请执行以下操作

当您迭代
过期的
项目时,您可以使用一个简单的变量对
金额
求和,当您找到第一个
等待
项目时,只需将该金额分配给
金额

 var sum: Float = 0f
 list.firstOrNull {
     sum += it.amount
     it.status == "WAIT"
 }?.apply {
     this.amount = sum
 }

事实上,你的代码并不是你想要的

计算状态为EXPIRED(如果存在)的所有元素的总和,并将类型为WAIT(如果存在)的第一个对象的数量添加到此总和中

它计算状态为过期(如果存在)的所有元素的总和,并将状态为过期(如果存在)的最后一个对象(如果存在)之后的类型为WAIT的第一个对象的金额或索引为1(如果存在)的对象的金额(如果不存在状态为过期的元素)相加:

println(GetRestructuringaMountPay(listOf(Test(“EXPIRED”,1f),Test(“WAIT”,1f),Test(“EXPIRED”,1f)))//将打印2.0,而按照原始描述,它应该是3.0
println(getRestructuringAmountToPay(listOf(Test(“WAIT”,1f),Test(“WAIT”,100f)))//将打印100.0,而按照最初的描述,它应该是1.0
要以Kotlin方式获得最初想要的行为,您需要执行以下操作:

if (list == null) return 0f //get rid of nullability
val (expired, waiting) = list.partition { it.status != "WAIT" } //split original list into respectful partitions
val sum = expired.map { it.amount }.sum() + (waiting.firstOrNull()?.amount ?: 0f) //do the calculations

Pretty是主观的——下面的代码很短,但无可否认,它没有利用集合的“排序”特性

fun sum(数据:列表):双倍{
val expiredSum=data.filter{it.status==“EXPIRED”}.sumByDouble{it.amount}
val waitSum=data.find{it.status==“WAIT”}?.amount?:0.0
返回expiredSum+waitSum
}

你说你想汇总所有状态为“等待”的项目,但似乎你做的恰恰相反。@Steve是的,对不起,更新了问题我必须同意你的意见我非常喜欢这个解决方案。它将我的老式解决方案的可读性与更现代的流媒体风格相结合。下次回到Kotlin编程时,我会把它作为模板记住。@Steve谢谢,我真的很感激!很好的解决方案!