scriban / scriban

A fast, powerful, safe and lightweight scripting language and engine for .NET

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Array reduction

igitur opened this issue · comments

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?

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.

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)

@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)
}}

An official array.reduce function would be really useful though. I'll try my hand at a PR.