librarylibs/Lists/src/Lists.xtl
Lists: list functions -- differences, windows, moving means, run lengths, chunks, shifts, interleaving, binary search, raze. Import it with an alias of your choice: "q:" u_se< "Lists". Put libs/Lists/src on XETAL_PATH ("just path"); the reference is libs/Lists/docs. Names with l: are exported; those under h: are private to this file.
Counts and sizes go on the left, the list on the right, as for the built-ins: 3 q:w_indows v.
Differences and windows
ˡd̲eltas : Num a => a -> a
d_eltas v: each item minus the one before (one fewer item).
ˡd̲eltas ← { v → (1 d̲rop v) − -1 d̲rop v }
ˡw̲indows : Int -> a -> a
n w_indows v: every run of n consecutive items, one per row.
ˡw̲indows ← { n v → n < 1 ? @ p̲anic< "a window holds 1 item or more, not {n}" k ← 1 + (t̲ally v) − n k < 1 ? (0 c̲at n) r̲eshape v ((r̲ange k) '+ t̲able o̲ffsets n) s̲elect v }
ˡm̲ovingMean : Num a => Int -> a -> Float
n m_ovingMean v: the mean of each window of n (a Float each).
ˡm̲ovingMean ← { n v → (f̲loat '+ r̲/₂ n ˡw̲indows v) ÷ f̲loat n }
Runs
ʰs̲tarts : (Eq a, Num b, Truthy b) => a -> b
Where each run of equal items starts (a 0/1 mask).
ʰs̲tarts ← { v → 0 = t̲ally v ? 0 r̲eshape 1 = 1◆ 1 c̲at (1 d̲rop v) ≠ -1 d̲rop v }
ˡr̲unValues : Eq a => a -> a
r_unValues v: the item of each run of equal items ("aaabcc" is "abc").
ˡr̲unValues ← { v → (ʰs̲tarts v) r̲eplicate v }
ˡr̲unLengths : Eq a => a -> Int
r_unLengths v: the length of each run ("aaabcc" is 3 1 2).
ˡr̲unLengths ← { v → ˡd̲eltas (w̲here ʰs̲tarts v) c̲at 1 + t̲ally v }
Reshaping
ˡc̲hunks : Int -> a -> Box a
n c_hunks v: v cut into pieces of n (the last may be shorter), as a list.
ˡc̲hunks ← { n v → n < 1 ? @ p̲anic< "a chunk holds 1 item or more, not {n}" (1 + (o̲ffsets t̲ally v) d̲iv n) p̲artition v }
ˡr̲aze : Box a -> a
r_aze list: the items of a list of lists joined into one list (APL2's enlist of a simple list). An empty list has no items to take a type's fill from: error[no-identity].
ˡr̲aze ← { b → 0 = t̲ally b ? @ p̲anic< "r_aze needs at least one list: an empty list has no items to join (nor a type to make an empty result of)" d̲isclose '{ e̲nclose (d̲isclose ⍺) c̲at d̲isclose ⍵ } r̲/ b }
ˡs̲hift : Int -> a -> a
n s_hift v: v moved n places toward the front (back for negative n), without wrapping: the places left empty get the fill (0, or a space).
ˡs̲hift ← { n v → t ← t̲ally v◆ n ≥ 0 ? t t̲ake n d̲rop v◆ (n̲eg t) t̲ake n d̲rop v }
ˡi̲nterleave : a -> a -> a
a i_nterleave b: a1 b1 a2 b2 ... (a and b of one length).
ˡi̲nterleave ← { a b → r̲avel₂ (2 c̲at t̲ally a) r̲eshape a c̲at b }
Searching
ʰb̲s : Ord a => a -> a -> Int -> Int -> Int
Binary search in sorted v between lo and hi: how many items are <= x.
ʰb̲s ← { v x lo hi → lo ≥ hi ? lo m ← (lo + hi + 1) d̲iv 2 (f̲irst m s̲elect v) ≤ x ? (((v ʰb̲s x)_ m)_ hi) ((v ʰb̲s x)_ lo)_ m − 1 }