简单地减少空数组将抛出:
线程“main”中的异常java.lang.UnsupportedOperationException:无法减少空迭代。
链接时的相同例外:
<script>
var tableobj = [
{table:{binding:""}},
{thead:{binding:"0"}},
{tbody:{binding:"0"}},
{tr:{binding:"00"}},
{th:{binding:"000"}},
{th:{binding:"000"}},
{th:{binding:"000"}}
];
function init(){
//GENERATE HTML & BIND PROPERTIES
var elementArray = generate(tableobj);
console.log(elementArray);
//ASSEMBLE THE TABLE --- example: elementArray[0].appendChild(thead)
var elementAssembly = assemble(elementArray);
console.log(elementAssembly);
console.log(elementAssembly[0]);
//OUTPUT
//TABlE->THEAD
//TABlE->THEAD
//TABlE->THEAD->TR
//TABlE->THEAD->TR->TH
//TABlE->THEAD->TR->TH
//TABlE->THEAD->TR->TH
}
function assemble(o){
o.forEach(function(ele){
var position = ele.position.replace(/0/g,"[0]");
var position = ele.position.split('');
if(ele.position.length > 0){
//WHERE MY QUESTION LIES....
var parent = o[position];
parent.appendChild(ele);
}
});
return o;
};
function generate(o){
var struct = o.map(function(ele,i){
var element = document.createElement(Object.keys(ele));
for(prop in ele){
var key = Object.keys(ele[prop]);
key.forEach(function(attr){
switch(attr){
case "binding":
Object.defineProperty(element,'position',{
value: ele[prop][attr]
});
break;
}
});
}
return element;
})
return struct;
}
//ONLOAD TRIGGER INIT
document.addEventListener('DOMContentLoaded', init);
</script>
是减少的预期操作还是错误?
有没有解决方法?
答案 0 :(得分:42)
异常是正确的,reduce
对空的iterable或数组不起作用。你可能正在寻找的是fold
,它接受一个起始值和一个对迭代的每个元素连续应用的操作。 reduce
将 first 元素作为起始值,因此不需要将其他值作为参数传递,但要求集合不为空。
fold
的使用示例:
println(intArrayOf().fold(0) { a, b -> a + b }) // prints "0"
答案 1 :(得分:1)
public inline fun <S, T : S> List<T>.reduceRightDefault(defaultIfEmpty: S, operation: (T, acc: S) -> S): S {
return if (isEmpty()) defaultIfEmpty
else reduceRight(operation)
}
用法:
val result = listOf<Boolean>().reduceRightDefault(false) { first, second -> first && second}
println("result $result")//result false
答案 2 :(得分:0)
我只想为无法使用fold(...)
的情况添加更多通用方法。因为,为了使用fold
,您需要能够表达一些初始值。
someIterable
.filter{ TODO("possibly filter-out everything") }
.takeIf{ it.isNotEmpty() }
?.reduce{ acc, element -> TODO("merge operation") }
?: TODO("value or exception for empty")
使用这种方法,在集合为空的情况下,reduce
将不会执行,因为takeIf
会将其转换为null
。最后,在这种情况下,我们可以使用elvis运算符表达一些值(或引发异常)。
您的示例:
intArrayOf(1, 2, 3)
.filter({ a -> a < 0 })
.takeIf{ it.isNotEmpty() }
?.reduce({ a, b -> a + b })
?: 0
答案 3 :(得分:0)
您可以使用foldRight:
println(listOf("1", "2", "3")
.filter { "not found" == it }
.foldRight("") { a, b -> a + b }) // prints: ""
println(listOf("1", "2", "3")
.filter { "not found" != it }
.foldRight("") { a, b -> a + b }) // prints: "123"
或您的情况:
val a = intArrayOf()
val b = a.foldRight(0) { memo, next -> memo + next } // b == 0
val a1 = intArrayOf(1, 2, 3)
val b1 = a.filter { a -> a < 0 }.foldRight(0) { a, b -> a + b } // b1 == 0