- testing-status
- listify
- concat
- first
- second
- end
- min-key/max-key
- group-by
- frequencies
- map-invert
- rand-sample
- sample
- shuffle
- union
- difference
- disj
- intersection
- subset
- superset
- overlaps
- update
- vals
- kvs
- merge
- merge-with
- select-keys
- get-in
- assoc-in
- update-in
- rename-keys
- index
- k
- sk
- destruct
- complement
- partial
- juxt
- constantly
- comp
- box
- memoize
- repeatedly
- reduce
- reduce-when
- reduce-while
- reduce-kv
- reductions
- filter
- remove
- into
- reverse
- distinct
- unique
- replace
- interleave
- interpose
- partition
- partition-all
- iterate
- take-nth
- take-while
- drop-while
- drop-last
- butlast
- some
- first-pred
- every
- not-every
- not-any
- keep
- map
- mapcat
- map-indexed
- zipmap
- keep-indexed
- pivot
225 tests passed out of 225
100% of tests are passing
Captures input and shoves it into a list.
put 1 2 3 | listify
listify 1 2 3
▶ [1 2 3]
A more generic version of base:concat2
, which takes any number of lists
concat [1 2 3] [4 5 6] [7 8 9]
put [1 2 3] [4 5 6] [7 8 9] | concat
▶ [1 2 3 4 5 6 7 8 9]
Returns the first element
first a b c
put a b c | first
▶ a
Returns the second element
second a b c
put a b c | second
▶ b
Returns the last element
end a b c
put a b c | end
▶ c
Returns the x for which (f x)
, a number, is least, or most.
If there are multiple such xs, the last one is returned.
min-key $math:sin~ (range 20)
▶ 11
max-key $math:sin~ (range 20)
▶ 14
Returns a map of elements keyed by (f x)
group-by $count~ a as asd aa asdf qwer
put a as asd aa asdf qwer | group-by $count~
▶ [&(num 1)=[a] &(num 2)=[as aa] &(num 3)=[asd] &(num 4)=[asdf qwer]]
group-by {|m| put $m[key]} [&key=a &val=1] [&key=b &val=1] [&key=a &val=3]
▶ [&a=[[&val=1 &key=a] [&val=3 &key=a]] &b=[[&val=1 &key=b]]]
Returns a map of the number of times a thing appears
frequencies (each $all~ [abba acdc rush bush])
each $all~ [abba acdc rush bush] | frequencies
▶ [&a=(num 3) &b=(num 3) &c=(num 2) &d=(num 1) &h=(num 2) &r=(num 1) &s=(num 2) &u=(num 2)]
Does what's on the tin
map-invert [&a=1 &b=2 &c=3]
▶ [&1=a &2=b &3=c]
Normally lossy.
map-invert [&a=1 &b=2 &c=1]
▶ [&1=c &2=b]
You can tell it not to be lossy, though.
map-invert [&a=1 &b=2 &c=1] &lossy=$false
▶ [&1=[a c] &2=[b]]
Returns items from @arr
with random probability of 0.0-1.0
rand-sample 0 (range 10)
MATCHES EXPECTATIONS: [nothing]
rand-sample 0.5 (range 10)
▶ 2
▶ 7
▶ 8
rand-sample 1 (range 10)
range 10 | rand-sample 1
▶ 0
▶ 1
▶ 2
▶ 3
▶ 4
▶ 5
▶ 6
▶ 7
▶ 8
▶ 9
Take n random samples from the input
sample 5 (range 10)
▶ 6
▶ 9
▶ 3
▶ 0
▶ 2
range 10 | sample 5
▶ 1
▶ 8
▶ 3
▶ 0
▶ 4
shuffle (range 10)
▶ 9
▶ 6
▶ 5
▶ 7
▶ 8
▶ 3
▶ 1
▶ 0
▶ 2
▶ 4
range 10 | shuffle
▶ 0
▶ 5
▶ 9
▶ 8
▶ 6
▶ 7
▶ 3
▶ 1
▶ 4
▶ 2
Set theory union
union [a b c] [d b e f] [g e h i]
put [a b c] [d b e f] [g e h i] | union
▶ a
▶ b
▶ c
▶ d
▶ e
▶ f
▶ g
▶ h
▶ i
Subtracts a bunch of sets from another
difference [a b c] [a d e]
▶ b
▶ c
difference [a b c] [a d e] [b f g]
put [a d e] [b f g] | difference [a b c]
▶ c
Like difference, but subtracts individual elements
disj [a b c d e f g] d e g
put d e g | disj [a b c d e f g]
▶ a
▶ b
▶ c
▶ f
Set theory intersection - returns only the items in all sets.
intersection [a b c]
▶ a
▶ b
▶ c
intersection [a b c] [b c d]
put [a b c] [b c d] | intersection
▶ b
▶ c
intersection [a b c] [b c d] [c d e]
▶ c
Predicate - returns true if l1 is a subset of l2. False otherwise
subset [a b c] [d e f b a c]
▶ $true
subset [d e f b a c] [c b a]
▶ $false
Predicate - returns true if l1 is a superset of l2. False otherwise
superset [d e f b a c] [a b c]
▶ $true
superset [a b c] [d e f b a c]
▶ $false
Predicate - returns true if l1 & l2 have a non-empty intersection.
overlaps [a b c d e f g] [e f g h i j k]
▶ $true
overlaps [a b c] [d e f]
▶ $false
Updates a map element by applying a function to the value.
update [&a=1] a $base:inc~
update [&a=0] a $'+~' 2
put 2 | update [&a=0] a $'+~' (one)
put 1 1 | update [&a=0] a $'+~' (all)
▶ [&a=(num 2)]
It works on lists, too.
update [1 2 2] 0 $base:inc~
▶ [(num 2) 2 2]
sister fn to keys
vals [&a=1 &b=2 &c=3]
▶ 1
▶ 2
▶ 3
Given [&k1=v1 &k2=v2 ...], returns a sequence of [k1 v1] [k2 v2] ...
kvs [&a=1 &b=2 &c=3]
▶ [a 1]
▶ [b 2]
▶ [c 3]
Merges two or more maps.
merge [&a=1 &b=2] [&c=3] [&d=4]
put [&a=1 &b=2] [&c=3] [&d=4] | merge
▶ [&a=1 &b=2 &c=3 &d=4]
Uses the last value if it sees overlaps. Pay attention to the a
in this example.
merge [&a=1 &b=2] [&a=3 &c=4]
▶ [&a=3 &b=2 &c=4]
Works with zero-length input.
merge [&]
merge [&] [&]
▶ [&]
Like merge, but takes a function which aggregates shared keys.
merge-with $'+~' [&a=1 &b=2] [&a=3 &c=4]
put [&a=1 &b=2] [&a=3 &c=4] | merge-with $'+~'
put $'+~' [&a=1 &b=2] [&a=3 &c=4] | merge-with (all)
▶ [&a=(num 4) &b=2 &c=4]
Returns a map with the requested keys.
select-keys [&a=1 &b=2 &c=3] a c
put a c | select-keys [&a=1 &b=2 &c=3]
▶ [&a=1 &c=3]
It won't add keys which aren't there.
select-keys [&a=1 &b=2 &c=3] a c d e f g
▶ [&a=1 &c=3]
It also works with lists.
select-keys [1 2 3] 0 0 2
▶ [&0=1 &2=3]
Returns nested elements. Nonrecursive.
get-in [&a=[&b=[&c=v]]] a b c
put a b c | get-in [&a=[&b=[&c=v]]]
▶ v
Works with lists.
get-in [0 1 [2 3 [4 v]]] 2 2 1
▶ v
Returns nothing when not found.
get-in [&a=1 &b=2 &c=3] a b c
MATCHES EXPECTATIONS: [nothing]
Nested assoc. Recursive
assoc-in [&] [a b c] v
assoc-in [&a=1] [a b c] v
assoc-in [&a=[&b=1]] [a b c] v
assoc-in [&a=[&b=[&c=1]]] [a b c] v
▶ [&a=[&b=[&c=v]]]
assoc-in [&a=1 &b=2] [a b c] v
▶ [&a=[&b=[&c=v]] &b=2]
Nested update. Recursive.
update-in [&a=[&b=[&c=(num 1)]]] [a b c] $base:inc~
▶ [&a=[&b=[&c=(num 2)]]]
Returns the map unchanged if not found.
update-in [&a=1 &b=2 &c=3] [a b c] $base:inc~
▶ [&a=1 &b=2 &c=3]
Returns map m
with the keys in kmap renamed to the vals in kmap
rename-keys [&a=1 &b=2] [&a=newa &b=newb]
▶ [&newa=1 &newb=2]
Won't produce key collisions
rename-keys [&a=1 &b=2] [&a=b &b=a]
▶ [&a=2 &b=1]
returns a map with the maps grouped by the given keys
index [[&name=betsy &weight=1000] [&name=jake &weight=756] [&name=shyq &weight=1000]] weight
put weight | index [[&name=betsy &weight=1000] [&name=jake &weight=756] [&name=shyq &weight=1000]]
▶ [&[&weight=1000]=[[&name=betsy &weight=1000] [&name=shyq &weight=1000]] &[&weight=756]=[[&name=jake &weight=756]]]
Takes a key and returns a closure which looks that key up in a map.
k a
▶ <closure 0xc000b295c0>
(k a) [&a=1 &b=2]
▶ 1
Like k
, but performs a safe lookup.
(k a) [&]
▶ [&reason=<unknown no such key: a> &stack-trace=<...>]
(sk a &miss=(num 0)) [&]
▶ 0
By default returns $nil
.
(sk a) [&]
▶ $nil
Works a bit like call, but returns a function.
+
doesn't work with a list...
+ [1 2 3]
▶ [&reason=<unknown wrong type for arg #0: must be number> &stack-trace=<...>]
But it does with destruct
(destruct $'+~') [1 2 3]
▶ 6
Returns a function which negates the boolean result
base:is-odd 1
(complement $base:is-odd~) 2
▶ $true
Curries arguments to functions
+ 1 2 3
(partial $'+~' 1) 2 3
(partial $'+~' 1 2) 3
put 2 3 | (partial $'+~' 1)
put 1 | partial $'+~' | (one) 2 3
▶ 6
Takes any number of functions and executes all of them on the input
(juxt $base:dec~ $base:inc~ $base:is-odd~ $base:is-even~ ) 1
put 1 | (juxt $base:dec~ $base:inc~ $base:is-odd~ $base:is-even~ )
put $base:dec~ $base:inc~ $base:is-odd~ $base:is-even~ | juxt | (one) 1
▶ 0
▶ 2
▶ $true
▶ $false
Takes @xs
. Returns a function which takes any number of args, and returns @xs
The builtin will throw an error if you give it input args.
(constantly a) 1 2 3
put 1 2 3 | (constantly a) (all)
put a | constantly | (one) 1 2 3
▶ a
(constantly [a b c]) 1 2 3
▶ [a b c]
(constantly a b c) 1 2 3
▶ a
▶ b
▶ c
Composes functions into a new fn. Contrary to expectation, works left-to-right.
(comp (partial $'*~' 5) (partial $'+~' 5)) 5
put 5 | (comp (partial $'*~' 5) (partial $'+~' 5))
put (partial $'*~' 5) (partial $'+~' 5) | comp | (one) 5
▶ 30
Returns a function which calls listify
on the result. The function must have parameters.
(box {|@xs| put $@xs}) 1 2 3
put 1 2 3 | (box {|@xs| put $@xs})
put {|@xs| put $@xs} | box (one) | (one) 1 2 3
▶ [1 2 3]
Caches function results so they return more quickly. Function must be pure.
memoize {|n| sleep 1; * $n 10}
▶ <closure 0xc0007fef00>
Here, $fixtures[f]
is a long running function.
time { $fixtures[f] 10 } | all
▶ 100
▶ 1.001022461s
time { $fixtures[f] 10 } | all
▶ 100
▶ 289.938µs
Takes a zero-arity function and runs it n
times
repeatedly 10 { randint 1000 }
▶ 539
▶ 363
▶ 31
▶ 835
▶ 721
▶ 744
▶ 248
▶ 540
▶ 72
▶ 379
Reduce does what you expect.
reduce $'+~' 1 2 3
put 1 2 3 | reduce $'+~'
put $'+~' 1 2 3 | reduce (all)
▶ 6
It's important to understand that reduce
only returns scalar values.
reduce $base:append~ [] 0 1 2
▶ [0 1 2]
reduce {|a b| assoc $a $@b} [&] [a 1] [b 2]
▶ [&a=1 &b=2]
You can get around this by using box
. comp
is defined similarly, for instance.
A fun thing to try is reductions
with the following test. Just remove the call to all
.
all (reduce (box {|a b| each {|x| put $x } $a; put $b }) [] 0 1 2 3 4 5)
▶ 0
▶ 1
▶ 2
▶ 3
▶ 4
▶ 5
convenience function for reduce
.
reduce {|acc n| if (base:is-odd $n) { + $acc $n } else { put $acc }} (range 20)
reduce-when {|acc n| base:is-odd $n} $'+~' (range 20)
reduce-when (comp $second~ $base:is-odd~) $'+~' (range 20)
▶ 100
short-curcuits the reduction when the predicate is met.
reduce-while {|acc n| < $n 10} $'+~' (range 20)
▶ 45
Like reduce, but the provided function params look like [accumulator key value]
instead of [accumulator value]
Most easily understood on a map. In this example we swap the keys and values.
reduce-kv {|a k v| assoc $a $v $k} [&] [&a=1 &b=2 &c=2]
put [&a=1 &b=2 &c=2] | reduce-kv {|a k v| assoc $a $v $k} [&] (one)
▶ [&1=a &2=c]
Varargs are treated as an associative list, using the index as the key
reduce-kv {|a k v| assoc $a $k $v} [&] a b c
put a b c | reduce-kv {|a k v| assoc $a $k $v} [&] (all)
put [&] a b c | reduce-kv {|a k v| assoc $a $k $v}
▶ [&(num 0)=a &(num 1)=b &(num 2)=c]
reduce-kv
doesn't have to return a map. Here, we also specify a starting index.
reduce-kv &idx=1 {|a k v| + $a (* $k $v)} 0 1 2 3
put 0 1 2 3 | reduce-kv &idx=1 {|a k v| + $a (* $k $v)}
▶ 14
Essentially reduce, but it gives the intermediate values at each step
reductions $'+~' 1 2 3
put 1 2 3 | reductions $'+~'
put $'+~' 1 2 3 | reductions (all)
▶ 1
▶ 3
▶ 6
Filter does what you expect. pfilter
works in parallel.
filter $base:is-even~ (range 1 10)
range 1 10 | filter $base:is-even~
▶ 2
▶ 4
▶ 6
▶ 8
It treats empty resultsets as $false.
filter {|n| if (== (% $n 2) 0) { put $true }} (range 1 10)
▶ 2
▶ 4
▶ 6
▶ 8
Same with $nil
.
filter {|n| if (== (% $n 2) 0) { put $true } else { put $nil }} (range 1 10)
▶ 2
▶ 4
▶ 6
▶ 8
Remove does what you expect. premove
works in parallel.
remove $base:is-odd~ (range 1 10)
range 1 10 | remove $base:is-odd~
▶ 2
▶ 4
▶ 6
▶ 8
Shoves some input into the appropriate container.
into [] 1 2 3
into [1] 2 3
put 1 2 3 | into []
put [] 1 2 3 | into (all)
▶ [1 2 3]
You can also shove into a map
into [&] [a 1] [b 2] [c 3]
into [&b=2] [a 1] [c 3]
put [a 1] [b 2] [c 3] | into [&]
▶ [&a=1 &b=2 &c=3]
Into takes optional arguments for getting keys/vals from the input.
use str; into [&] &keyfn=$put~ &valfn=$str:to-utf8-bytes~ (all stuff)
▶ [&f=0x66 &s=0x73 &t=0x74 &u=0x75]
Into also takes an optional argument for handling collisions.
use str; into [&] &keyfn=$put~ &valfn=(box $str:to-utf8-bytes~) &collision=$base:concat2~ (all stuff)
▶ [&f=[0x66 0x66] &s=[0x73] &t=[0x74] &u=[0x75]]
Does what's on the tin.
reverse (range 6)
range 6 | reverse
▶ 5
▶ 4
▶ 3
▶ 2
▶ 1
▶ 0
Returns a set of the elements in @arr
.
Does not care about maintaining order.
distinct 1 2 2 3 3 3 4 4 4 4 5 5 5 5 5
distinct 1 2 3 2 3 3 4 4 5 5 5 4 4 5 5
put 1 2 2 3 3 3 4 4 4 4 5 5 5 5 5 | distinct
▶ 1
▶ 2
▶ 3
▶ 4
▶ 5
It doesn't care about mathematical equality
distinct 1 1.0 (num 1) (num 1.0)
▶ 1.0
▶ 1
▶ 1.0
▶ 1
Like uniq
but works with the data pipe.
unique 1 2 2 3 3 3 4 4 4 4 5 5 5 5 5
put 1 2 2 3 3 3 4 4 4 4 5 5 5 5 5 | unique
▶ 1
▶ 2
▶ 3
▶ 4
▶ 5
Includes an optional count
parameter.
unique &count=$true 1 2 2 3 3 3 4 4 4 4 5 5 5 5 5
put 1 2 2 3 3 3 4 4 4 4 5 5 5 5 5 | unique &count=true
▶ [(num 1) 1]
▶ [(num 2) 2]
▶ [(num 3) 3]
▶ [(num 4) 4]
▶ [(num 5) 5]
It doesn't care about mathematical equality
unique 1 1.0 (num 1) (num 1.0)
▶ 1
▶ 1.0
▶ 1
▶ 1.0
Returns an "array" with elements of coll
replaced according to smap
.
Works with combinations of lists & maps.
replace [zeroth first second third fourth] [(num 0) (num 2) (num 4) (num 0)]
▶ zeroth
▶ second
▶ fourth
▶ zeroth
replace [&2=two &4=four] [4 2 3 4 5 6 2]
▶ four
▶ two
▶ 3
▶ four
▶ 5
▶ 6
▶ two
replace [&[city london]=[postcode wd12]] [&name=jack &city=london &id=123] | into [&]
▶ [&name=jack &postcode=wd12 &id=123]
Returns an "array" of the first item in each list, then the second, etc.
interleave [a b c] [1 2 3]
▶ a
▶ 1
▶ b
▶ 2
▶ c
▶ 3
Understands mismatched lengths
interleave [a b c d] [1 2 3]
interleave [a b c] [1 2 3 4]
▶ a
▶ 1
▶ b
▶ 2
▶ c
▶ 3
Returns an "array" of the elements seperated by sep
.
interpose , one
▶ one
interpose , one two
▶ one
▶ ,
▶ two
interpose , one two three
▶ one
▶ ,
▶ two
▶ ,
▶ three
partitions an array into lists of size n.
partition 3 (range 12)
range 12 | partition 3
▶ [(num 0) (num 1) (num 2)]
▶ [(num 3) (num 4) (num 5)]
▶ [(num 6) (num 7) (num 8)]
▶ [(num 9) (num 10) (num 11)]
Drops items which don't complete the specified list size.
range 14 | partition 3
▶ [(num 0) (num 1) (num 2)]
▶ [(num 3) (num 4) (num 5)]
▶ [(num 6) (num 7) (num 8)]
▶ [(num 9) (num 10) (num 11)]
Specify &step=n
to specify a "starting point" for each partition.
range 12 | partition 3 &step=5
▶ [(num 0) (num 1) (num 2)]
▶ [(num 5) (num 6) (num 7)]
&step
can be < than the partition size.
range 4 | partition 2 &step=1
▶ [(num 0) (num 1)]
▶ [(num 1) (num 2)]
▶ [(num 2) (num 3)]
When there are not enough items to fill the last partition, a pad can be supplied.
range 14 | partition 3 &pad=[a]
▶ [(num 0) (num 1) (num 2)]
▶ [(num 3) (num 4) (num 5)]
▶ [(num 6) (num 7) (num 8)]
▶ [(num 9) (num 10) (num 11)]
▶ [(num 12) (num 13) a]
The size of the pad may exceed what is used.
range 13 | partition 3 &pad=[a b]
▶ [(num 0) (num 1) (num 2)]
▶ [(num 3) (num 4) (num 5)]
▶ [(num 6) (num 7) (num 8)]
▶ [(num 9) (num 10) (num 11)]
▶ [(num 12) a b]
...or not.
range 13 | partition 3 &pad=[]
▶ [(num 0) (num 1) (num 2)]
▶ [(num 3) (num 4) (num 5)]
▶ [(num 6) (num 7) (num 8)]
▶ [(num 9) (num 10) (num 11)]
▶ [(num 12)]
Convenience function for partition
which supplies &pad=[]
.
Use when you don't want everything in the resultset.
partition-all 3 (range 13)
range 13 | partition-all 3
▶ [(num 0) (num 1) (num 2)]
▶ [(num 3) (num 4) (num 5)]
▶ [(num 6) (num 7) (num 8)]
▶ [(num 9) (num 10) (num 11)]
▶ [(num 12)]
Returns an array of (f x), (f (f x)), (f (f (f x)) ...)
, up to the nth element.
iterate $base:inc~ 10 (num 1)
▶ 1
▶ 2
▶ 3
▶ 4
▶ 5
▶ 6
▶ 7
▶ 8
▶ 9
▶ 10
My favorite example of iterate is to generate fibonacci numbers. In increasingly functional style:
iterate {|l| put [$l[1] (+ $l[0] $l[1])]} 10 [(num 1) (num 1)] | each $base:first~
iterate (destruct {|a b| put [$b (+ $a $b)]}) 10 [(num 1) (num 1)] | each $base:first~
iterate (box (destruct (juxt $second~ $'+~'))) 10 [(num 1) (num 1)] | each $base:first~
▶ 1
▶ 1
▶ 2
▶ 3
▶ 5
▶ 8
▶ 13
▶ 21
▶ 34
▶ 55
Emits every nth element.
take-nth 2 (range 10)
range 10 | take-nth 2
▶ 0
▶ 2
▶ 4
▶ 6
▶ 8
Emits items until (f x)
yields an empty or falsey value.
take-while (complement (partial $'<=~' 5)) (range 10)
range 10 | take-while {|n| < $n 5 }
take-while {|n| if (< $n 5) { put $true } } (range 10)
▶ 0
▶ 1
▶ 2
▶ 3
▶ 4
Emits items until (f x)
yields a non-empty or truthy value.
drop-while (complement (partial $'<=~' 5)) (range 10)
range 10 | drop-while {|n| < $n 5 }
drop-while {|n| if (< $n 5) { put $true } } (range 10)
▶ 5
▶ 6
▶ 7
▶ 8
▶ 9
Drops the last n elements of @arr
.
drop-last 2 (range 10)
range 10 | drop-last 2
▶ 0
▶ 1
▶ 2
▶ 3
▶ 4
▶ 5
▶ 6
▶ 7
Drops the last element of @arr
.
butlast (range 10)
range 10 | butlast
▶ 0
▶ 1
▶ 2
▶ 3
▶ 4
▶ 5
▶ 6
▶ 7
▶ 8
Returns the first truthy (f x)
If f is a true predicate (takes an element, returns $true or $false), some
tells you if at least one (any/some) x satisfies the predicate.
Opposite function is not-any
some (partial $'>~' 5) (range 10)
range 10 | some (partial $'>~' 5)
▶ $true
some
is useful for lots of things, but you probably want one of the other functions.
first-pred (comp $math:sin~ (partial $'<~' (num 0.9))) (range 10)
range 10 | first-pred (comp $math:sin~ (partial $'<~' (num 0.9)))
▶ 2
returns true if each x satisfies the predicate.
range 20 | each $math:sin~ [(all)] | every {|n| <= -1 $n 1}
▶ $true
opposite of every
.
returns true if at least one x fails to satisfy the predicate.
range 20 | each $math:sin~ [(all)] | not-every {|n| <= -1 $n 1}
▶ $false
opposite of some
.
returns true if none of the elements satisfy the predicate
range 20 | each $math:sin~ [(all)] | not-any {|n| > $n 1}
▶ $true
Returns an "array" of non-empty & non-nil results of (f x)
. pkeep
works in parallel.
keep {|x| if (base:is-even $x) { put $x }} (range 1 10)
keep {|x| if (base:is-even $x) { put $x } else { put $nil }} (range 1 10)
range 1 10 | keep {|x| if (base:is-even $x) { put $x }}
▶ 2
▶ 4
▶ 6
▶ 8
Additionally, you can specify your own predicate function instead.
keep (partial $'*~' 3) (range 1 10) &pred=$base:is-even~
▶ 6
▶ 12
▶ 18
▶ 24
map
is a more powerful than each
. It works with "array" values and reads from the pipe. pmap
works in parallel.
map $base:inc~ (range 5)
range 5 | map $base:inc~
each $base:inc~ [(range 5)]
▶ 1
▶ 2
▶ 3
▶ 4
▶ 5
Unlike each
, map
understands what to do with multiple lists.
map $'+~' [1 2 3] [4 5 6] [7 8 9] [10 11 12]
▶ 22
▶ 26
▶ 30
It also understands mismatches
map $'+~' [1 2 3] [4 5 6] [7 8 9] [10 11 12 13 14 15]
▶ 22
▶ 26
▶ 30
If you can, supply the optional parameters for faster performance.
For most operations, &lists=$false
is enough.
map $base:inc~ (range 5) &lists=$false
▶ 1
▶ 2
▶ 3
▶ 4
▶ 5
When working with lists, supply &els
for faster performance.
map $'+~' [1 2 3] [4 5 6] [7 8 9] [10 11 12] &lists=$true &els=3
▶ 22
▶ 26
▶ 30
map
can still process multiple lists the way that each
does. Just set &lists=$false
.
each $base:first~ [[1 2 3] [4 5 6] [7 8 9]]
map $base:first~ [1 2 3] [4 5 6] [7 8 9] &lists=$false
▶ 1
▶ 4
▶ 7
Applies concat to the result of (map f xs)
. Here for convenience.
mapcat (box (destruct $reverse~)) [3 2 1] [6 5 4] [9 8 7] &lists=$false
▶ [1 2 3 4 5 6 7 8 9]
Here's some shenanigans. What does it mean? You decide.
mapcat (box $reverse~) [3 2 1] [6 5 4] [9 8 7] &els=(num 3)
▶ [9 6 3 8 5 2 7 4 1]
Like map but the index is the first parameter
map-indexed {|i x| put [$i $x]} (all stuff)
all stuff | map-indexed {|i x| put [$i $x]}
▶ [(num 0) s]
▶ [(num 1) t]
▶ [(num 2) u]
▶ [(num 3) f]
▶ [(num 4) f]
Returns a map with the keys mapped to the corresponding vals
zipmap [a b c] [1 2 3]
▶ [&a=1 &b=2 &c=3]
Understands mismatches
zipmap [a b c d] [1 2 3]
zipmap [a b c] [1 2 3 4]
▶ [&a=1 &b=2 &c=3]
Returns all non-empty & non-nil results of (f index item)
.
keep-indexed {|i x| if (base:is-odd $i) { put $x } else { put $nil }} a b c d e f g
▶ b
▶ d
▶ f
Of course, this works just as well.
map-indexed {|i x| if (base:is-odd $i) { put $x } } a b c d e f g
▶ b
▶ d
▶ f
And supply your own predicate.
keep-indexed {|i x| put [$i $x]} a b c d e f g &pred=(comp $base:first~ $base:is-odd~)
▶ [(num 1) b]
▶ [(num 3) d]
▶ [(num 5) f]
Tables are an "array" of maps with a non-empty intersection of keys.
This function pivots them.
pivot [&name=daniel &weight=1000 &height=900] ^
[&name=david &weight=800 &height=700] ^
[&name=vincent &weight=600 &height=500]
put [&name=daniel &weight=1000 &height=900] ^
[&name=david &weight=800 &height=700] ^
[&name=vincent &weight=600 &height=500] ^
| pivot
▶ [&name=weight &david=800 &daniel=1000 &vincent=600]
▶ [&name=height &david=700 &daniel=900 &vincent=500]
Pivoting adds a new column called name
and also uses the name
coumn to identify each row, but this is configurable.
pivot [&foo=daniel &weight=1000 &height=900] ^
[&foo=david &weight=800 &height=700] ^
[&foo=vincent &weight=600 &height=500] ^
&from_row=foo &to_row=bar
▶ [&david=800 &daniel=1000 &bar=weight &vincent=600]
▶ [&david=700 &daniel=900 &bar=height &vincent=500]