Skip to content

Instantly share code, notes, and snippets.

@leumasme
Last active January 17, 2024 15:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save leumasme/7cd51daee6b766d000a1d40a746349e9 to your computer and use it in GitHub Desktop.
Save leumasme/7cd51daee6b766d000a1d40a746349e9 to your computer and use it in GitHub Desktop.
Javascript: Array.down() and Array.up()

Array.up() and Array.down() let you do semi-basic array processing without nesting Array.map() calls.
This is a silly thing I made in 20 minutes because I thought it would be cursed. You probably shouldn't actually use it.
Somewhat inspired by vectorized functions in python.

// Function calls between down() and up() will be executed on all elements instead.
["hey","pizza","man"].down().startsWith("m").up()
// => [false, false, true]
// It also works with multiple function calls in a series
"yellow,green,blue".split(",").down().substring(2).repeat(2).up().join("+")
// => "llowllow+eeneen+ueue"
// You can also go multiple levels deep
`5-3,2-4
5-5,1-1`.split("\n").down().split(",").down().split("-").up().up()
// => [
// [ ["5", "3"], ["2", "4"] ],
// [ ["5", "5"], ["1", "1"] ]
// ]
// ^ The last example would usually be written as:
`5-3,2-4
5-5,1-1`.split("\n").map(l => l.split(",").map(e => e.split("-")))
const UP = Symbol("up");
Array.prototype.down = function () {
console.assert(Array.isArray(this));
return wrap(this);
}
Array.prototype.up = function () {
console.assert(Array.isArray(this));
let upper = this[UP];
if (!upper) throw new Error("this is not a wrapped array");
return upper
}
function wrap(target) {
let fake = new Proxy(target, {
get: function (target, prop) {
if (prop == UP) return target;
let res = makeDeepFunc(target, prop);
return res
}
})
return fake
}
function makeDeepFunc(target, name) {
// If the elements don't have UP, then an up() call is actually meant for the array and not for the elements
if (name == "up" && !target[0][UP]) return target.up;
return (...args) => {
let result = [];
for (let item of target) {
result.push(item[name](...args));
}
return wrap(result)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment