179 lines
3.0 KiB
Plaintext
179 lines
3.0 KiB
Plaintext
use ./common
|
|
use ./num
|
|
|
|
var -l~ = $common:to-list~
|
|
var -c~ = $common:cexec~
|
|
var '++~' = $'num:++~'
|
|
var is-neg~ = $num:is-neg~
|
|
|
|
|
|
fn indexes {|&from=0 &step=1 @argv|
|
|
var c = (count (-l $@argv))
|
|
var from = (-c (is-neg $from) (+ $from $c) $from)
|
|
var to = (-c (is-neg $step) -1 $c)
|
|
if (and (>= $from 0) (< $from $c)) {
|
|
range &step=$step $from $to
|
|
}
|
|
}
|
|
|
|
fn loop {|&from=0 &step=1 @argv|
|
|
var l = (-l $@argv)
|
|
indexes &from=$from &step=$step $l | each {|i|
|
|
put [ $i $l[$i] ]
|
|
}
|
|
}
|
|
|
|
fn foreach {|&from=0 &step=1 &end=$false cb @argv|
|
|
if (not $end) {
|
|
loop &from=$from &step=$step $@argv | each {|e| $cb $@e}
|
|
} else {
|
|
loop &from=$from &step=$step $@argv | each {|e|
|
|
if ($end $@e) {
|
|
break
|
|
}
|
|
$cb $@e
|
|
}
|
|
}
|
|
}
|
|
|
|
fn pforeach {|&from=0 &step=1 cb @argv|
|
|
loop &from=$from &step=$step $@argv | peach {|e| $cb $@e}
|
|
}
|
|
|
|
fn reach {|cb @argv|
|
|
foreach &from=-1 &step=-1 {|_ e| $cb $e} $@argv
|
|
}
|
|
|
|
fn reverse {|@argv|
|
|
reach $put~ $@argv
|
|
}
|
|
|
|
fn is-empty {|@argv|
|
|
num:is-zero (count (-l $@argv))
|
|
}
|
|
|
|
fn is-not-empty {|@argv|
|
|
not (is-empty $@argv)
|
|
}
|
|
|
|
fn filter {|cb @argv|
|
|
each {|e|
|
|
-c ($cb $e) $e $nop~
|
|
} (-l $@argv)
|
|
}
|
|
|
|
fn filter-not {|cb @argv|
|
|
filter {|v| not ($cb $v)} $@argv
|
|
}
|
|
|
|
fn contains {|cb @argv|
|
|
var cb2~ = (common:cond (eq (kind-of $cb) fn) $cb {|e| eq $cb $e})
|
|
each {|e|
|
|
if (cb2 $e) {
|
|
put $true
|
|
return
|
|
}
|
|
} (-l $@argv)
|
|
put $false
|
|
}
|
|
|
|
fn contains-not {|cb @argv|
|
|
not (contains $cb $@argv)
|
|
}
|
|
|
|
fn search {|cb @argv|
|
|
foreach {|i e|
|
|
-c ($cb $i $e) [$i $e] $nop~
|
|
} $@argv
|
|
}
|
|
|
|
fn search-not {|cb @argv|
|
|
search {|i e| not ($cb $i $e) } $@argv
|
|
}
|
|
|
|
fn exists {|cb @argv|
|
|
var r = $false
|
|
foreach {|i e|
|
|
if ($cb $i $e) {
|
|
set r = $true
|
|
break
|
|
}
|
|
} $@argv
|
|
put $r
|
|
}
|
|
|
|
fn exists-not {|cb @argv|
|
|
not (exists $cb $@argv)
|
|
}
|
|
|
|
fn search-first {|&from=$nil &reverse=$false cb @argv|
|
|
var step = (-c $reverse -1 1)
|
|
if (not $from) {
|
|
set from = (-c $reverse -1 0)
|
|
}
|
|
foreach &from=$from &step=$step {|i e|
|
|
if ($cb $i $e) {
|
|
put [$i $e]
|
|
break
|
|
}
|
|
} $@argv
|
|
}
|
|
|
|
fn first {|&from=$nil &reverse=$false cb @argv|
|
|
search-first &from=$from &reverse=$reverse {|_ e| $cb $e} $@argv | each {|e|
|
|
put $e[1]
|
|
break
|
|
}
|
|
}
|
|
|
|
fn reduce {|acc cb @argv|
|
|
each {|e|
|
|
set acc = ($cb $acc $e)
|
|
} (-l $@argv)
|
|
put $acc
|
|
}
|
|
|
|
fn remove-duplicate {|@argv|
|
|
var done = [&]
|
|
each {|e|
|
|
if (not (has-key $done $e)) {
|
|
set done[$e] = $nil
|
|
put $e
|
|
}
|
|
} (-l $@argv)
|
|
}
|
|
|
|
fn swap {|i j @argv|
|
|
var l = (-l $@argv)
|
|
var c = (count $l)
|
|
if (< $i 0) {
|
|
set i = (+ $i $c)
|
|
}
|
|
if (< $j 0) {
|
|
set j = (+ $j $c)
|
|
}
|
|
if (or (is-neg $i) (is-neg $j) (>= $i $c) (>= $j $c)) {
|
|
fail 'index out of range'
|
|
}
|
|
if (== $i $j) {
|
|
all $l
|
|
} else {
|
|
if (> $i $j) {
|
|
set i j = $j $i
|
|
}
|
|
take $i $l
|
|
put $l[$j]
|
|
all $l[(++ $i)..$j]
|
|
put $l[$i]
|
|
drop (++ $j) $l
|
|
}
|
|
}
|
|
|
|
fn less {|cb|
|
|
put {|a b| < ($cb $a $b) 0 }
|
|
}
|
|
|
|
fn sort {|cb @argv|
|
|
order &less-than=(less $cb) (-l $@argv)
|
|
}
|