简单等同于 ES6 中的 `const [...butLast, last] = values`?

Simple equivalent to `const [...butLast, last] = values` in ES6?

以下是无效的 ES6 语法,但也许有一种简单的方法可以完成同样的事情,例如,使用 Ramda?

const [...butLast, last] = values

您可以反转数组,使用标准的 ...rest 运算符,然后将其余的反转回来:

const initAndLast = (arr) => (([last, ...butLast]) => [butLast.reverse(), last])([...arr].reverse())

const [bl1, l1] = initAndLast([1, 2, 3]);

console.log(`butLast: ${JSON.stringify(bl1)}, last: ${l1}`)

const [bl2, l2] = initAndLast([1]);

console.log(`butLast: ${JSON.stringify(bl2)}, last: ${l2}`)

使用 ramda,您可以将 R.init 和 R.last 与 R.juxt 一起使用:

const initAndLast = R.juxt([R.init, R.last]);

const [bl1, l1] = initAndLast([1, 2, 3]);

console.log(`butLast: ${JSON.stringify(bl1)}, last: ${l1}`)

const [bl2, l2] = initAndLast([1]);

console.log(`butLast: ${JSON.stringify(bl2)}, last: ${l2}`)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>

如果你使用的是 ramda,你可以这样做

const values = [1, 2, 3]
const [butLast, Last] = [R.dropLast(1, values), R.last(values)]

R.dropLast(n, arr):returns 数组 arr 的副本,删除了最后 n 个元素 R.last(arr): returns 数组中的最后一个元素

您可以使用Array.prototype.slice()Array.prototype.pop()

let values = [1,2,3,4,5];
// copy `values` array using `.slice()`, `.pop()` the copy
// alternatively `values.pop()` to remove last element from `values`
const [butLast, last] = [values, values.slice(0).pop()];

console.log(butLast, last);

你看问题的方式不对。您不希望在解构赋值的开头使用 rest 运算符。你想要的是从数组的末尾而不是开头获取元素。剩余运算符的位置与期望的结果无关。

在解构赋值的 object destructuring 部分中存在两个概念,它们共同使您可以仅使用语言提供的内容来完成您真正想要的。

这两个概念是:

  1. 正在将属性值分配给名称不同于 属性 的标识符。

    const { thing: otherthing } = { thing: 1 };
    console.log(otherthing, thing); // 1, undefined
    
  2. 动态访问属性:

    const prop = 'thing';
    const { [prop]: otherthing } = { thing: 1 };
    console.log(otherthing, thing); // 1, undefined
    

这两个概念结合数组是对象这一事实,允许您执行以下操作:

const values = [1,2,3,4,5,6,7,8,9];
const { [values.length - 1]: last, ...rest } = values;
console.log(last, Object.values(rest)); // 9 [1,2,3,4,5,6,7,8]

缺点是:

  • 你必须知道数组的长度,所以你必须在解构之前存储数组,或者在解构赋值中包含长度属性:

    const { length, [length - 1]: last, ...rest } = [1,2,3,4,5,6,7,8,9];
    console.log(last, Object.values(rest)); // 9 [1,2,3,4,5,6,7,8]
    
  • 如果你希望剩余赋值的结果是一个真正的数组你必须像上面那样使用Object.values()将剩余赋值的结果转换回数组,但是你可以将其包装在 IIFE 中以防止范围干扰(这也可以防止先前缺点的范围干扰):

    const { last, rest } = (({ length: l, [l-1]: last, ...rest } = [1,2,3,4,5,6,7,8,9]) =>
                            ({ last, rest: Object.values(rest) }))();
    console.log(last, rest); // 9 [1,2,3,4,5,6,7,8]