range evaluates an expression for each element of a vector/object, effectively
allowing to loop over them. Note that this is not intended to actually modify
the source vector/object, for those tasks map and
filter should be used instead. range is less often used,
especially with over functions that would have side effects or to build up
counters/sums.
range returns the value of the last evalauted expression. Note that since
objects are iterated in effectively random order, one should not rely on the
return value of range when ranging over objects.
(range ["foo" "bar"] [value] (print $value))➜nil(range {a "b" c "d"} [key value] (print $key))➜nil
sourceis an arbitrary expression.paramsis a vector describing the desired loop variable name(s).expris an arbitrary expression.
range evaluates the source argument and coalesces it to a vector or object,
with vectors being preferred. If either of these operations fail, an error is
returned. The naming vector params then allows to set the index/value (for
vectors) or key/value (for objects) as variables, which can then be used in the
expression expr, for example:
(range .data [v] (set! .data.users[$v] = "foo"))(range .data [v] (set! $var (+ (try $var 0) 1)))
params must be a vector containing one or two identifiers. If a single
identifier is given, it's the variable name for the value. If two identifiers
are given, the first is used for the index/key, the second is used for the value.
expr can then be any expression. Just like the other form, source is
evaluated and coalesced to vector/object and the expression is then applied to
each element.
range evaluates all expressions using a shared context, so it's possible for
the expressions to share variables.