Array reduction
igitur opened this issue · comments
Francois Botha commented
Hi,
I'm looking for a way to reduce arrays, e.g. I was hoping for something like this:
total_length = ["Apple", "Banana", "Computer", "Mobile Phone", "Orange", "Sofa", "Table"] | array.each @string.size | array.reduce @math.plus
Or in the case of summing, just
total_length = ["Apple", "Banana", "Computer", "Mobile Phone", "Orange", "Sofa", "Table"] | array.each @string.size | math.plus
But I can't find an obvious way. Is array reduction missing?
Francois Botha commented
I even tried this:
total = 0
{{ ["Apple", "Banana", "Computer", "Mobile Phone", "Orange", "Sofa", "Table"] | array.each @string.size | array.each @(do; total = total + $0; ret total; end) | array.last }}
This actually works, but yields a weird answer of 138.
Alexandre Mutel commented
Yeah, there is nothing builtin. Easiest might be to create your own C# function or you can try to define a Scriban function like this:
func reduce(a0, f0); $total = null; for $x in a0; if $total == null; $total = f0($x); else; $total += f0($x); end; end; ret $total; end;
total_length = ["Apple", "Banana", "Computer", "Mobile Phone", "Orange", "Sofa", "Table"] | reduce(@array.size)
Francois Botha commented
@xoofx Ah, great thanks.
I used that as base and came up with a more generic reduce function:
{{
func reduce(a0, f0); $result= null; for $x in a0; if $result== null; $result = $x; else; $result= $result | f0 $x; end; end; ret $result; end;
["Apple", "Banana", "Computer", "Mobile Phone", "Orange", "Sofa", "Table"] | array.each @string.size | reduce(@math.plus)
}}
Or with custom function:
{{
func reduce(a0, f0); $result= null; for $x in a0; if $result== null; $result = $x; else; $result= $result | f0 $x; end; end; ret $result; end;
product(x,y) = x * y
["Apple", "Banana", "Computer", "Mobile Phone", "Orange", "Sofa", "Table"] | array.each @string.size | reduce(@product)
}}
Francois Botha commented
An official array.reduce
function would be really useful though. I'll try my hand at a PR.