--- a/crates/jrsonnet-evaluator/src/builtin/mod.rs +++ b/crates/jrsonnet-evaluator/src/builtin/mod.rs @@ -92,6 +92,7 @@ ("native".into(), builtin_native), ("filter".into(), builtin_filter), ("map".into(), builtin_map), + ("flatMap".into(), builtin_flatmap), ("foldl".into(), builtin_foldl), ("foldr".into(), builtin_foldr), ("sortImpl".into(), builtin_sort_impl), @@ -331,6 +332,40 @@ }) } +fn builtin_flatmap(context: Context, _loc: Option<&ExprLocation>, args: &ArgsDesc) -> Result { + parse_args!(context, "flatMap", args, 2, [ + 0, func: ty!(function) => Val::Func; + 1, arr: ty!((array | string)); + ], { + match arr { + Val::Str(s) => { + let mut out = String::new(); + for c in s.chars() { + match func.evaluate_values(context.clone(), &[Val::Str(c.to_string().into())])? { + Val::Str(o) => out.push_str(&o), + _ => throw!(RuntimeError("in std.join all items should be strings".into())), + }; + } + Ok(Val::Str(out.into())) + }, + Val::Arr(a) => { + let mut out = Vec::new(); + for el in a.iter() { + let el = el?; + match func.evaluate_values(context.clone(), &[el])? { + Val::Arr(o) => for oe in o.iter() { + out.push(oe?) + }, + _ => throw!(RuntimeError("in std.join all items should be arrays".into())), + }; + } + Ok(Val::Arr(out.into())) + }, + _ => unreachable!(), + } + }) +} + fn builtin_foldl(context: Context, _loc: Option<&ExprLocation>, args: &ArgsDesc) -> Result { parse_args!(context, "foldl", args, 3, [ 0, func: ty!(function) => Val::Func; --- a/crates/jrsonnet-stdlib/src/std.jsonnet +++ b/crates/jrsonnet-stdlib/src/std.jsonnet @@ -188,14 +188,7 @@ else { [k]: func(k, obj[k]) for k in std.objectFields(obj) }, - flatMap(func, arr):: - if !std.isFunction(func) then - error ('std.flatMap first param must be function, got ' + std.type(func)) - else if std.isArray(arr) then - std.flattenArrays(std.makeArray(std.length(arr), function(i) func(arr[i]))) - else if std.isString(arr) then - std.join('', std.makeArray(std.length(arr), function(i) func(arr[i]))) - else error ('std.flatMap second param must be array / string, got ' + std.type(arr)), + flatMap:: $intrinsic(flatMap), join:: $intrinsic(join),