// Arrays hold any mix of values, in any order var a = [1, "two", true, null, [4, 5], {x: 6}, undefined, function() { return 8; }]; assert(len(a) == 8); assert(a[0] == 1); assert(a[1] == "two"); assert(a[2] == true); assert(isnull(a[3])); assert(a[4][1] == 5); assert(a[5].x == 6); assert(isundefined(a[6])); assert(a[7]() == 8); // Pushing every type, one after the other, onto one array var b = []; push(b, 1); push(b, "s"); push(b, false); push(b, null); push(b, [1]); push(b, {k: 1}); push(b, undefined); push(b, tostr); push(b, 2.5); push(b, "again"); assert(len(b) == 10); assert(b[0] == 1 && b[1] == "s" && b[2] == false && isnull(b[3])); assert(b[4][0] == 1 && b[5].k == 1 && isundefined(b[6]) && isfunction(b[7])); assert(b[8] == 2.5 && b[9] == "again"); // An element can be replaced by a value of a different type var c = [1, 2, 3]; c[0] = "text"; c[1] = [true]; c[2] = null; assert(c[0] == "text" && c[1][0] == true && isnull(c[2])); c[0] = 1; c[1] = {a: 1}; c[2] = false; assert(c[0] == 1 && c[1].a == 1 && c[2] == false); // Every way of adding to an array takes any type var d = [1]; unshift(d, "front"); insert(d, 1, null); insertarr(d, 0, [true, {z: 1}]); merge(d, ["tail", 3]); assert(len(d) == 7); assert(d[0] == true && d[1].z == 1 && d[2] == "front" && isnull(d[3]) && d[4] == 1 && d[5] == "tail" && d[6] == 3); fill(d, "x", 2); push(d, 1); assert(deepequal(d, ["x", "x", 1])); // Arrays that were emptied or created by builtins take any type too empty(d); push(d, "a"); push(d, 1); assert(deepequal(d, ["a", 1])); var parts = split("a,b", ","); push(parts, 3); push(parts, null); assert(len(parts) == 4 && parts[2] == 3); var mapped = map([1, 2], function(v) { return v; }); push(mapped, "text"); assert(mapped[2] == "text"); var sliced = subarr([1, 2, 3], 0, 2); push(sliced, "text"); assert(sliced[2] == "text"); var cloned = clone([1, 2]); push(cloned, "text"); assert(cloned[2] == "text"); var deep = deepclone([1, 2]); push(deep, [1]); assert(len(deep) == 3); var flat = flatten([[1], [2]]); push(flat, "text"); assert(flat[2] == "text"); var taken = splice([1, 2, 3], 0, 2); push(taken, "text"); assert(taken[2] == "text"); // flatten and merge of arrays of different types var flatMixed = flatten([[1, "a"], [true], [null, [2]]]); assert(len(flatMixed) == 5); assert(flatMixed[1] == "a" && flatMixed[2] == true && isnull(flatMixed[3]) && flatMixed[4][0] == 2); var mergedMixed = [1, 2]; merge(mergedMixed, ["a", "b"]); assert(deepequal(mergedMixed, [1, 2, "a", "b"])); // Mixed arrays join, print and search assert(join([1, "a", true, null], ",") == "1,a,true,null"); assert(tostr([1, "a", true, null]) == "[1, \"a\", true, null]"); assert(indexof([1, "1", true], "1") == 1); assert(indexof([1, "1", true], true) == 2); assert(indexof([0, "", false, null], false) == 2); assert(indexof([0, "", false, null], null) == 3); // Iterating a mixed array var seen = ""; foreach(var v : [1, "b", true, null, [1]]) seen += tostr(v) + ";"; assert(seen == "1;b;true;null;[1];"); // Mixed arrays filter, map and reduce var kinds = map([1, "a", true, null], function(v) { if(isnull(v)) return "null"; if(v == 1) return "one"; return tostr(v); }); assert(deepequal(kinds, ["one", "a", "true", "null"])); var onlyStrings = [1, "a", 2, "b", null, "c"]; filter(onlyStrings, function(v) { return v != null && v != 1 && v != 2; }); assert(deepequal(onlyStrings, ["a", "b", "c"])); var count = reduce([1, "a", null, true, [1]], function(acc, v) { return acc + 1; }, 0); assert(count == 5); // Mixed arrays reverse, clone and compare var m = [1, "a", null]; reverse(m); assert(isnull(m[0]) && m[1] == "a" && m[2] == 1); assert(deepequal(clone(m), m)); assert(!deepequal([1, "a"], ["a", 1])); // Sorting a mix with a comparer that puts numbers before strings var sortable = ["b", 2, "a", 1]; sort(sortable, false, function(x, y) { var xs = x == tostr(x); var ys = y == tostr(y); if(xs == ys) return 0; if(xs) return 1; return -1; }); assert(deepequal(sortable, [2, 1, "b", "a"]));