Home > OS >  In Javascript, is there an easyish way to get a chainable Array prepend operation like the reverse o
In Javascript, is there an easyish way to get a chainable Array prepend operation like the reverse o

Time:07-14

I'm doing array manipulation in Javascript, and I want to be able to chain operations with multiple calls to map, concat, etc.

const someAmazingArrayOperation = (list) => 
  list
    .map(transformStuff)
    .sort(myAwesomeSortAlgorithm)
    .concat([someSuffixElement])
    .precat([newFirstElement])
    .filter(unique)

But the problem I've run into is that Array.precat doesn't exist. (Think of Array.concat, but the reverse.)

I don't want to modify Array.prototype in my own code, for reasons. (https://flaviocopes.com/javascript-why-not-modify-object-prototype/)

I could totally use Array.concat and concatenate my array to the end of the prefix array and carry on. But that doesn't chain with the other stuff, and it makes my code look clunky.

It's kind of a minor issue because I can easily write code to get the output I want. But it's kind of a big deal because I want my code to look clean and this seems like a missing piece of the Array prototype.

Is there a way to get what I want without modifying the prototype of a built-in type?

For more about the hypothetical Array.precat, see also: concat, but prepend instead of append

CodePudding user response:

You could use Array#reduce with a function which takes the initialValue as array for prepending data.

const
    precat = (a, b) => [...a, b],
    result = [1, 2, 3]
        .reduce(precat, [9, 8, 7]);

console.log(result)

CodePudding user response:

If you don't want to modify Array.prototype, you can consider extends:

class AmazingArray extends Array {
    precat(...args) {
        return new AmazingArray().concat(...args, this);
    }
}

const transformStuff = x => 2*x;
const myAwesomeSortAlgorithm = (a, b) => a - b;
const someSuffixElement = 19;
const newFirstElement = -1;
const unique = (x, i, arr) => arr.indexOf(x) === i;

const someAmazingArrayOperation = (list) => 
  new AmazingArray()
    .concat(list)
    .map(transformStuff)
    .sort(myAwesomeSortAlgorithm)
    .concat([someSuffixElement])
    .precat([newFirstElement])
    .filter(unique);
    
console.log(someAmazingArrayOperation([9, 2, 2, 3]));

CodePudding user response:

I don't want to modify Array.prototype in my own code, for reasons.

These reasons are good, but you can sidestep them by using a collision-safe property - key it with a symbol, not a name:

const precat = Symbol('precatenate')
Array.prototype[precat] = function(...args) {
  return [].concat(...args, this);
};

const someAmazingArrayOperation = (list) => 
  list
    .map(transformStuff)
    .sort(myAwesomeCompareFunction)
    .concat([someSuffixElement])
    [precat]([newFirstElement])
    .filter(unique);
  • Related