if (word(2 $loadinfo()) != [pf]) { load -pf $word(1 $loadinfo()); return; }; unload data_array; package data_array; # # Array manipulation functions. # # # General one liners. Brief description: # # The *item functions operate on one array element. # The *items functions operate on as many elements as there are args. # # Note that unlike their inbuilt counterparts, these generally accept negative # item numbers as the distance from the top of the array, starting with -1. # # Let's start with some basics: # # getndelitems: splice the items $1- from the array and return them as a list. # getndelindex: splice the indices $1- from the array and return them as a list. # getnrolitems: Splice items $2- from $0, put them at the end of $1, and return them. # itemnorm: Supporting function. Fixes/removes invalid item numbers. # alias itemnorm (ar,it) {@:ni=numitems($ar);fe it it {@it+=0<=it?0:ni,it=0<=it&&it numitems else setranditem. # setuniqitem[s]: setnextitem if the array item[s] doesn't already exist. # alias setnextitem (ar,args) {return $setitem($ar $numitems($ar) $args)}; alias setnextitems (ar,args) {fe args foo {@foo=setitem($ar $numitems($ar) $foo)};return $args}; alias setranditem (ar,args) {return $setitem($ar $rand($numitems($ar)) $args)}; alias setranditems (ar,args) {fe args foo {@foo=setitem($ar $rand($numitems($ar)) $foo)};return $args}; alias setrmaxitem (ar,it,args) {@:ni=numitems($ar);return $setitem($ar ${it>ni?ni:rand($ni)} $args)}; alias setrmaxitems (ar,it,args) {@:ni=numitems($ar);fe args foo {@foo=setitem($ar ${it>ni?ni++:rand($ni)} $foo)};return $args}; alias setuniqitem (ar,args) {if (0>finditem($ar $args)){return $setitem($ar $numitems($ar) $args)}}; alias setuniqitems (ar,args) {fe args foo {@foo=0>finditem($ar $foo)?setitem($ar $numitems($ar) $foo):-1};return $args}; alias getwordmatches (ar,args) { @ :items = jot(0 $numitems($ar)); fe args args { @ :mask = shift(args); push args $getmatches($ar $mask); push args $getmatches($ar $mask *); push args $getmatches($ar * $mask); push args $getmatches($ar * $mask *); @ items = common($args / $items); }; return $numsort($uniq($items)); return $numsort($uniq($args)); }; # # Delete contents matching $1- of array $0. # If an arg isn't specified, it equates to *. # alias array.purge (args) { @ :mask = []; @ :aray = #args ? getarrays($shift(args)) : args; fe ($aray) foo { @ 1>#args ? delarray($foo) : delitems($foo $getmatches($foo $args)); }; }; alias array.shift (mask,array) { fe ($array) array { fe ($getarrays($array)) array { if (:dest) {getanrmitems $array $dest $mask;}; @ :dest = array; }; }; }; # # Simple enough.. Remove all duplicates leaving just one in each array. # stack push alias.x; alias alias.x (args) { alias $args; @ sar(gr/uniq/deluniq/args); @ sar(gr/[] : ix/ix : []/args); alias $args; }; alias.x array.uniq (args) { fe ($args) arg { fe ($getarrays($arg)) ar { @ :ix = jot(0 $numitems($ar)); fe ix ix { @ ix = ix == finditem($ar $getitem($ar $ix)) ? [] : ix; }; @ delitems($ar $ix); }; }; }; stack pop alias alias.x; # # Remove all items found in one array from the others. # stack push alias.x; alias alias.x (args) { alias $args; @ sar(gr/rfilter/filter/args); @ sar(gr/getmatches\(\$array/getmatches\(\$arrays/args); @ sar(gr/finditem\(\$arrays/finditem\(\$array/args); @ sar(gr/delitems\(\$array/delitems\(\$arrays/args); @ sar(gr/getitem\(\$array/getitem\(\$arrays/args); alias $args; }; alias.x array.arfilter (mask,arrays) { fe arrays arrays {@ :arrays = getarrays($arrays)}; @ :arrays = uniq($arrays); while ((:array = shift(arrays)) && arrays) { array.rfilter $array $mask $arrays; }; }; alias.x array.rfilter (array,mask,arrays) { fe ($arrays) arrays { fe ($getarrays($arrays)) arrays { if (array == arrays) {continue} @ :del = getmatches($array $mask); fe del item { @ item = 0 > finditem($arrays $getitem($array $item)) ? [] : item; }; @ delitems($array $del); }; }; }; stack pop alias alias.x; alias array.historicalfilter (array,mask,arrays) { fe ($arrays) arrays { fe ($getarrays($arrays)) arrays { if (array == arrays) {continue} @ :del = getmatches($arrays $mask); fe del item { @ item = 0 > finditem($array $getitem($arrays $item)) ? [] : item; }; @ delitems($arrays $del); }; }; }; # # array.read: Load files $1- into array $0 # array.nread: Load files $* into arrays of the same name. # u prefixed functions only adds unique lines. # stack push alias alias.x; stack push alias alias.xx; alias alias.x (args) { alias.xx $args; @ sar(gr/uread/nuread/args); @ sar(gr/@ :fd = open($fn r);/@ :fd = open($fn r), :it = numitems($fn);/args); @ sar(gr/@ :ar = shift(args), :it = numitems($ar);//args); @ sar(gr/fn/ar/args); alias.xx $args; }; alias alias.xx (args) { alias $sar(/, :it = numitems\(\$ar\)//$args); @ sar(gr/uread/read/args); @ sar(gr/setuniqitem\(\$ar/usetitem\(\$ar \${it++}/args); alias $args; }; alias.x array.uread (args) { @ :ar = shift(args), :it = numitems($ar); fe ($glob($args)) fn { @ :fd = open($fn r); while ((:dt = read($fd)) || !eof($fd)) { #@ usetitem($ar ${it++} $dt); @ setuniqitem($ar $dt); }; @ close($fd); }; }; # # Load files $* into arrays of the same name. # alias array.historicalnread (args) { fe ($glob($args)) fn { @ :it = numitems($fn); @ :fd = open($fn r); while ((:dt = read($fd)) || !eof($fd)) { @ usetitem($fn ${it++} $dt); #@ setuniqitem($fn $dt); }; @ close($fd); }; }; stack pop alias alias.xx; stack pop alias alias.x; # # Give a brief summary of all matching arrays, or all arrays. alias array.stat { fe ($getarrays($*)) foo { echo $[-7]numitems($foo) /$[-10]#listarray($foo) /$[-10]@listarray($foo) $foo; }; }; # # I tried to clean these up. Really I did. Just give me some time. # # Brief summary: # .dump/.grep displays matching contents of matching arrays (in different ways). # .codump/.cogrep as above but sews together multiple arrays for displaying. # .idump/.igrep/.coidump/.coigrep sorted versions of above. # .write/.iwrite/.nwrite/.niwrite inverse of .read, differing in the order in which lines are written. # .flush/.iflush/.nflush/.niflush write and delete the arrays. # stack push alias alias.x; stack push alias alias.xx; alias alias.xx (args) { alias $args; @ sar(gr/grep/dump/args); @ sar(gr/-nobanner/-banner/args); @ sar(gr/ -- / -- [\$[-4]item \$[-2]#content \$[-3]@content] /args); alias $args; }; alias alias.x (args) { alias.xx $args; @ sar(gr/igrep/grep/args); @ sar(gr/igetitem/getitem/args); @ sar(gr/igetmatches/getmatches/args); alias.xx $args; }; alias.x array.igrep (arrays default *, mask default *) { fe ($getarrays($arrays)) array { echo $numitems($array)/$#listarray($array)/$@listarray($array) $array; fe ($igetmatches($array $mask)) item { @ :content = igetitem($array $item); xecho -nobanner -- $content; } } echo $chr(2)$#getarrays($arrays)$chr(2) arrays listed; }; alias.x array.coigrep (array, mk, args) { fe ($getarrays($array)) array { fe ($igetmatches($array $afterw($mk $args))) item { @ :content = igetitem($array $item); fe ($beforew($mk $args)) foo { push content $igetitem($foo $item); }; xecho -nobanner -- $content; }; }; }; alias alias.x (args) { alias $args; fe (write flush getmatches getitem) foo { @ sar(gr/i$foo/$foo/args); }; alias $args; }; alias.x array.iwrite (args) { @ :fd = open($shift(args) w); fe ($getarrays($shift(args))) foo { fe ($igetmatches($foo ${args?args:[*]})) bar { @ write($fd $igetitem($foo $bar)); }; }; @ close($fd); }; alias.x array.niwrite (args) { fe ($getarrays($shift(args))) foo { @ :fd = open($foo w); fe ($igetmatches($foo ${args?args:[*]})) bar { @ write($fd $igetitem($foo $bar)); }; @ close($fd); }; }; alias.x array.iflush {array.iwrite $*;array.purge $1-;}; alias.x array.niflush {array.niwrite $*;array.purge $*;}; stack pop alias alias.xx; stack pop alias alias.x;