简体   繁体   English

在 Javascript 中,是否有一种简单的方法来获得可链接的 Array 前置操作,如 Array.concat 的反向操作?

[英]In Javascript, is there an easyish way to get a chainable Array prepend operation like the reverse of Array.concat?

I'm doing array manipulation in Javascript, and I want to be able to chain operations with multiple calls to map, concat, etc.我正在用 Javascript 进行数组操作,我希望能够通过多次调用 map、concat 等来链接操作。

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.但我遇到的问题是Array.precat不存在。 (Think of Array.concat , but the reverse.) (想想Array.concat ,但反过来。)

I don't want to modify Array.prototype in my own code, for reasons.出于某种原因,我不想在自己的代码中修改Array.prototype ( https://flaviocopes.com/javascript-why-not-modify-object-prototype/ ) 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.我完全可以使用Array.concat并将我的数组连接到前缀数组的末尾并继续。 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.但这很重要,因为我希望我的代码看起来很干净,这似乎是 Array 原型的缺失部分。

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有关假设的 Array.precat 的更多信息,另请参阅: concat,但 prepend 而不是 append

You could use Array#reduce with a function which takes the initialValue as array for prepending data.您可以将Array#reduce与一个函数一起使用,该函数将initialValue作为数组用于前置数据。

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

I don't want to modify Array.prototype in my own code, for reasons .出于某种原因,我不想在自己的代码中修改Array.prototype

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);

If you don't want to modify Array.prototype , you can consider extends :如果不想修改Array.prototype ,可以考虑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]));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM