new object $list: $libraries; var $root created_on = 796268969; var $root flags = ['methods, 'code, 'variables, 'core]; var $root help_node = $help_obj_list; var $root inited = 1; var $root managed = [$list]; var $root manager = $list; public method ._vcolumnize() { arg list, lines, cols, width, @other; var outlist, line, i, j, sep; [(sep ?= " ")] = other; width -= sep.length(); lines = (lines > (list.length())) ? (list.length()) : lines; outlist = []; for i in [1 .. lines] { line = (list[i]).pad(width); for j in [1 .. cols] (| (line = (line + sep) + ((list[i + (j * lines)]).pad(width))) |); outlist += [line.trim('right)]; } return outlist; }; public method .add() { arg list, element; return (> setadd(list, element) <); }; public method .addkey() { arg l, key, val; var i; i = find i in [1 .. l.length()] where (((l[i])[1]) == key); anticipate_assignment(); return i ? replace(l, i, [key, val]) : (l + [[key, val]]); }; public method .affix() { arg l1, l2; var last, first; // Combines l1 and l2 by appending the first element of l2 to the last // of l1. if (type(l2) != 'list) l2 = [l2]; last = (| l1.last() |) || ""; first = (| l2[1] |) || ""; l1 = [@l1.chop(), last + first]; if ((l2.length()) > 1) l1 += l2.subrange(2); return l1; }; public method .center_lines() { arg lines, width, @args; var line, fmt; fmt = ("%" + width) + "c"; return map line in (lines) to (strfmt(fmt, line)); }; public method .chop() { arg list, @count; // chops the last <count> elements off the list. // return [] if count is longer then the list. count = count || 1; anticipate_assignment(); return (| sublist(list, 1, listlen(list) - count) |) || []; }; public method .columnize() { arg list, cols, @rest; var width, lines, line, separator, linelength, curcol; // turn [...] into ". . ." // rest[1]==separator; rest[2]==linelength [(separator ?= " "), (linelength ?= 78)] = rest; width = (linelength / cols) - (separator.length()); lines = []; while (list) { line = (list[1]).pad(width); list = list.subrange(2); for curcol in [2 .. cols] { if (list) { line = (line + separator) + ((list[1]).pad(width)); list = list.subrange(2); } } lines += [line]; } return lines; }; public method .compress() { arg list; var x; // [a,a,b,b,c,c,d,d] => [a,b,c,d] // removes duplicate entries in a list return hash x in (list) to ([x, 1]).keys(); }; public method .count() { arg list, elem; var count, i; // count of elem in list for i in (list) { if (i == elem) count++; } return count; }; public method .del() { arg list, element; return (> setremove(list, element) <); }; public method .delete(): native; public method .delkey() { arg l, key; var i; i = find i in [1 .. l.length()] where (((l[i])[1]) == key); anticipate_assignment(); return i ? delete(l, i) : l; }; public method .element_maxlength() { arg list; var i, s, t; s = 0; for i in (list) { if ((t = strlen(tostr(i))) > s) s = t; } return s; }; public method .flatten() { arg list; var toret, elem; // [[[x], x], x] => [x, x, x] toret = []; for elem in (list) { if (type(elem) == 'list) toret += .flatten(elem); else toret += [elem]; } return toret; }; public method .fold() { arg list, object, method, @args; var i, out; // apply object.method to a current result and the next element, return the // result switch (list.length()) { case 0: return 0; case 1: return list[1]; } out = list[1]; for i in (sublist(list, 2, listlen(list) - 1)) out = object.(method)(out, i, @args); return out; }; public method .format() { arg list, format; return strfmt(format, @list); }; public method .getkey() { arg l, key; var i, x; if (!(x = find i in [1 .. l.length()] where (((l[i])[1]) == key))) throw(~keynf, "Key not found."); return (l[x])[2]; }; public method .getkey_index() { arg l, key; var i, x; if (!(x = find i in [1 .. l.length()] where (((l[i])[1]) == key))) throw(~keynf, "Key not found."); return x; }; public method .grep() { arg lines, regexp; var line, result, out, reg; out = []; for line in [1 .. lines.length()] { if ((reg = match_regexp(lines[line], regexp))) out += [[line, reg, lines[line]]]; } return out; }; public method .insert(): native; public method .join(): native; public method .last() { arg list; return list[listlen(list)]; }; public method .lcolumnize() { arg list, @args; var line, part, lines, max, cols, col, width, len, sep; [(len ?= (| sender().linelen() |) || 78), (sep ?= " ")] = args; lines = []; line = ""; max = (.element_maxlength(list)) + (sep.length()); cols = (len > max) ? (len / max) : 1; width = (len / cols) - (sep.length()); col = cols; for part in (list) { col = col - 1; if (!col) { lines = lines + [line + part]; line = ""; col = cols; continue; } line = line + (part.pad(width)); } if (line) return lines + [line]; return lines; }; public method .length(): native; public method .lmap() { arg list, method, @args; var x, s; // call methods for each thing in list on sender() s = sender(); return map x in (list) to (s.(method)(x, @args)); }; public method .make() { arg n, @elt; var i; [(elt ?= 0)] = elt; return map i in [1 .. n] to (elt); }; public method .map_to_english() { arg list, method, @args; return .to_english(.mmap(list, method, @args)); }; public method .map_to_string() { arg list, method, @args; return .join(.mmap(list, method, @args)); }; public method .match_nth() { arg objs, str, nth; var obj, n; n = nth; for obj in (objs) { if (obj.match_name(str)) { if (!--n) return obj; } } throw(~match, ((("There are not " + ((.numbers())[nth])) + " ") + str) + "'s available."); }; public method .match_object() { arg objs, str; var obj, found; found = []; for obj in (objs) { if (obj.match_name(str)) found += [obj]; } if (listlen(found) == 1) return found[1]; if (listlen(found) > 1) throw(~ambig, "ambiguous match", found); throw(~objnf, "Object not found."); }; public method .max() { arg list; return (| max(@list) |) || 0; }; public method .mfilter() { arg list, method, @args; var x; // similar to .mmap, but returns a list of objects which returned a // true value from 'method. return filter x in (list) where (x.(method)(@args)); }; public method .min() { arg list; return (| min(@list) |) || 0; }; public method .mmap() { arg list, method, @args; var x; // call 'method on each object, return results. return map x in (list) to (x.(method)(@args)); }; public method .mmap_objects() { arg list, method, @args; var x; return map x in (list) to ((type(x) == 'objnum) ? x.(method)(@args) : x); }; public method .nonzero() { arg list; var x; return filter x in (list) where (x); }; public method .nth_element_maxlength() { arg lists, element; var list; // Returns longest string whose index is element in one of the lists in // lists. if (type(element) != 'integer) throw(~type, "Second argument is not an integer"); if (type(lists) != 'list) throw(~type, "First argument is not a list"); return map list in (lists) to (tostr(list[element]).length()).max(); }; public method .numbered_text() { arg text; var line; // receives a list of strings, returns that list with line numbers // prepended return map line in [1 .. text.length()] to ("%3r: %l".format(line, text[line])); }; public method .numbers() { // returns a list of numbers return ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"]; }; public method .omap() { arg list, object, method, @args; var obj; // calls object.method(obj, @args) for each obj in list return map obj in (list) to (object.(method)(obj, @args)); }; public method .prefix() { arg list, prefix; var elem; return map elem in (list) to (prefix + elem); }; public method .random() { arg list; return list[random(listlen(list))]; }; public method .replace(): native; public method .reverse() { arg list; var i, len; // .reverse(list) // -> list with its elements reversed len = (list.length()) + 1; return map i in [1 .. len - 1] to (list[len - i]); }; public method .set_contains() { arg @args; var super, list, element; // True if the first list given is a superset of all subsequent lists. // False otherwise. [] is a superset of [] and nothing else; anything is // a superset of []. If only one list is given, return true. super = args ? (args[1]) : []; for list in (delete(args, 1)) { for element in (list) { if (!(element in super)) return 0; } } return 1; }; public method .set_difference() { arg @args; var set, list, element; // Usage: diff(set 1, set 2, ..., set n) // Returns all elements of set 1 that are not in sets 2..n if (!args) return []; set = args[1]; anticipate_assignment(); for list in (delete(args, 1)) { for element in (list) set = setremove(set, element); } return set; }; public method .set_equal() { arg set1, set2; var e, dict1, dict2; // True if the two lists given contain the same elements. // False otherwise. dict1 = hash e in (set1) to ([e, 1]); dict2 = hash e in (set2) to ([e, 1]); for e in (dict1.keys()) { if (!dict_contains(dict2, e)) return 0; } for e in (dict2.keys()) { if (!dict_contains(dict1, e)) return 0; } return 1; }; public method .set_intersection() { arg l1, l2; var i, out; // set intersection if the arguments out = []; for i in (l1) { if (i in l2) out = out.setadd(i); } return out; }; public method .setadd(): native; public method .setremove(): native; public method .setremove_all() { arg list, remove; var part; if (type(list) != 'list) throw(~type, "First argument must be a list."); if (type(remove) != 'list) throw(~type, "Second argument must be a list."); anticipate_assignment(); for part in (remove) list = setremove(list, part); return list; }; public method .slice() { arg big_list, element; var list, i; // Return elementh' element of all lists in big_list // No type or length checking done for speed purposes. // element can be a list, in which cases, a list of list is returned if (type(element) == 'integer) return map list in (big_list) to (list[element]); else return map list in (big_list) to (map i in (element) to (list[i])); }; public method .sort(): native; public method .subrange(): native; public method .sum() { arg data; var ret, i; // returns a sum of each element in the list. [ret, @data] = data; for i in (data) ret += i; return ret; }; public method .swap() { arg list, a, b; var holder; // swap elements at indexes a and b if ((listlen(list) < a) || ((listlen(list) < b) || ((a < 1) || (b < 1)))) throw(~args, "Index specifiers are outside the range of the list."); anticipate_assignment(); holder = list[a]; list = replace(list, a, list[b]); list = replace(list, b, holder); return list; }; public method .tabulate() { arg list, headers, @rest; var i, j, t, t1, trim_cols, header_sep, colsizes, len; if (!list) return []; [(colsizes ?= 0), (trim_cols ?= 0), (header_sep ?= " "), (len ?= 79)] = rest; if (!headers) headers = .make(list.length(), []); if (type(headers[1]) == 'string) headers = map i in (headers) to ([i]); // Find the column sizes if (!colsizes) { if (trim_cols) { t = map i in (list) to (refresh() && ((i.element_maxlength()) + 2)); t1 = filter i in [1 .. t.length()] where ((t[i]) > 2); t = map i in (t1) to (t[i]); list = map i in (t1) to (list[i]); headers = map i in (t1) to (headers[i]); } colsizes = t ? map i in [1 .. headers.length()] to (refresh() && max(t[i], ((headers[i]).element_maxlength()) + 2)) : map i in [1 .. list.length()] to (refresh() && (max((headers[i]).element_maxlength(), (list[i]).element_maxlength()) + 2)); } t = map i in (colsizes) to (("%" + i) + "l").sum(); t1 = map i in (colsizes) to (((("%" + i) + "{") + header_sep) + "}l").sum(); // Now format the thing... return map i in (headers.transpose()) to (refresh() && (((t1.format(@i)).pad(len)).trim('right))) + map i in (list.transpose()) to (refresh() && (((t.format(@i)).pad(len)).trim('right))); }; public method .to_buffer() { arg @args; return (> strings_to_buf(@args) <); }; public method .to_dict() { arg list; var a; return hash a in (list) to (a); }; public method .to_english() { arg list, @options; var empty, and, sep; [(empty ?= "nothing"), (and ?= " and "), (sep ?= ", ")] = options; switch (list.length()) { case 0: return empty; case 1: return tostr(list[1]); } return (join(list.delete(list.length()), sep) + and) + tostr(list[list.length()]); }; public method .transpose() { arg list; return $math.transpose(list); }; public method .union(): native; public method .valid_objects() { arg list; var obj; return filter obj in (list) where (valid(obj)); }; public method .vcolumnize() { arg list, cols, @rest; var linelength, sep, width, lines, i, j, line, outlist; [(linelength ?= (| sender().linelen() |) || 78), (sep ?= " ")] = rest; lines = ((list.length()) / cols) + (((list.length()) % cols) ? 1 : 0); width = linelength / cols; return ._vcolumnize(list, lines, cols, width, sep); }; public method .vcolumnize2() { arg list, lines, @rest; var linelength, sep, cols, width, i, j, line, outlist; [(linelength ?= (| sender().linelen() |) || 78), (sep ?= " ")] = rest; cols = ((list.length()) / lines) + (((list.length()) % lines) ? 1 : 0); width = linelength / cols; return ._vcolumnize(list, lines, cols, width, sep); }; public method .vcolumnize3() { arg list, lines, @rest; var linelength, cols, width, i, j, line, outlist; [(linelength ?= (| sender().linelen() |) || 78)] = rest; cols = ((list.length()) / lines) + (((list.length()) % lines) ? 1 : 0); width = linelength / cols; outlist = []; for i in [1 .. lines] { line = ""; for j in [0 .. cols] (| (line = line + ((list[i + (j * lines)]).pad(width))) |); outlist += [line]; } return outlist; }; public method .vcolumnize4() { arg list, @args; var linelength, sep, lines, cols, width, max; [(linelength ?= (| sender().linelen() |) || 79), (sep ?= " ")] = args; max = (.element_maxlength(list)) + (sep.length()); cols = (linelength > max) ? (linelength / max) : 1; width = linelength / cols; lines = ((list.length()) / cols) + (((list.length()) % cols) ? 1 : 0); return ._vcolumnize(list, lines, cols, width, sep); };