【问题标题】:Destructuring to get the last element of an array in es6解构以获取es6中数组的最后一个元素
【发布时间】:2016-01-08 22:38:51
【问题描述】:

在咖啡脚本中这很简单:

coffee> a = ['a', 'b', 'program']
[ 'a', 'b', 'program' ]
coffee> [_..., b] = a
[ 'a', 'b', 'program' ]
coffee> b
'program'

es6 是否允许类似的东西?

> const [, b] = [1, 2, 3]                              
'use strict'                                           
> b  // it got the second element, not the last one!                      
2                                                      
> const [...butLast, last] = [1, 2, 3]          
SyntaxError: repl: Unexpected token (1:17)                                                                                                                                                        
> 1 | const [...butLast, last] = [1, 2, 3]                                                                                                                                                        
    |                  ^                                                                                                                                                                          
    at Parser.pp.raise (C:\Users\user\AppData\Roaming\npm\node_modules\babel\node_modules\babel-core\node_modules\babylon\lib\parser\location.js:24:13)                                           

我当然可以用 es5 的方式来做 -

const a = b[b.length - 1]

但也许这有点容易出错。 splat 只能是解构中的最后一件事吗?

【问题讨论】:

  • @FelixKling 这个问题特别是关于 ... 在 es6 中的行为,特别是它只能在解构或参数列表中用作最后一件事。这对于从咖啡脚本进入 es6 的人来说可能是违反直觉的,因此这个问题可能很有用。
  • 这意味着除了[1,2,3].slice(-1),你甚至不能解构等价于[1,2,3].slice(0, -1)。这些是常见的操作。 ES6 解构在某种程度上是个笑话!
  • @Iven 有正当理由 - 处理无限迭代。
  • 太糟糕的休息,因为第一个参数不起作用。本来会很酷...这是一个使用一些答案的jsperf jsperf.com/destructure-last/1

标签: ecmascript-6 destructuring


【解决方案1】:

console.log('last', [1, 3, 4, 5].slice(-1));
console.log('second_to_last', [1, 3, 4, 5].slice(-2));

【讨论】:

  • 不错的简单非变异解决方案。
  • @Shanimal 取决于,我得到pop 版本更快(OS X,Chrome 68)。
  • @Dave Newton 但是 pop() 导致突变
  • @AntonioPantano 是的,它会改变副本。关键是它是否更快不是给定的。
  • 返回值'program' 而不是['program'] 使用['a','b','program'].slice(-1)[0]。对于空数组,这将返回 undefined
【解决方案2】:

我相信 ES6 至少可以提供帮助:

[...arr].pop()

鉴于您的数组 (arr) 不是未定义的并且是一个可迭代元素(是的,即使字符串也可以工作!!),它应该返回最后一个元素..即使是空数组,它也不会改变它。虽然它创建了一个中间数组..但这不应该花费太多。

您的示例将如下所示:

  console.log(  [...['a', 'b', 'program']].pop() );

【讨论】:

  • 呃,很糟糕,即使.slice(-1)[0] 稍微不那么糟糕,或者var [last]=arr.slice().reverse() 是另一个丑陋的,如果你需要的话
  • 我以为这篇文章是关于 ES6/ES2015 的,不是吗?但我特别喜欢你的最后一块。将两者结合起来怎么样:var [last] = arr.slice(-1) ;)
  • 我最喜欢的方式是Object.defineProperty(Array.prototype, -1, { get() {return this[this.length - 1] } }); [1,2,3][-1]
  • 虽然这可行,但它是可变的,会从原始数组中删除该项目。在许多情况下并不理想。
  • @GavKilbride 它没有。示例与 [].concat(arr).pop(); 相同,它不会改变 arr
【解决方案3】:

这在 ES6/2015 中是不可能的。标准只是没有提供它。

正如您在the spec 中看到的,FormalParameterList 可以是:

  • FunctionRestParameter
  • FormalsList(参数列表)
  • FormalsList,后跟FunctionRestParameter

没有提供FunctionRestParameter 后跟参数。

【讨论】:

    【解决方案4】:

    你可以解构反转的数组以接近你想要的。

    const [a, ...rest] = ['a', 'b', 'program'].reverse();
      
    document.body.innerHTML = 
        "<pre>"
        + "a: " + JSON.stringify(a) + "\n\n"
        + "rest: " + JSON.stringify(rest.reverse())
        + "</pre>";

    【讨论】:

    • 聪明。比const last = ['bbb', 'uuu', 'iii'].slice(-1); 更好?在性能方面?
    • .slice(-1) 在技术上更快,但它不会在一次调用中同时提供最后一项和子数组,这是解构时... splat 的好处。在更长的数组上使用时要考虑反转两次的性能损失,但是对于一个小脚本可能值得方便吗?但是,如果您仍然想要 ES5 中的 oneliner,您也可以很容易地 let a = array.slice(-1), rest = array.slice(0,array.length-2),这大约快 4%。 jsperf.com/last-array-splat
    【解决方案5】:

    另一种方法是:

    const arr = [1, 2, 3, 4, 5]
    const { length, [length - 1]: last } = arr; //should be 5
    console.log(last)

    【讨论】:

    • 您不必赶上length...rest 会更有用。
    • @КонстантинВан 是的,这很常见,我的很少见,但真的很有用
    【解决方案6】:

    不一定是最高效的做法。但根据上下文,一种非常优雅的方式是:

    const myArray = ['one', 'two', 'three'];
    const theOneIWant = [...myArray].pop();
    
    console.log(theOneIWant); // 'three'
    console.log(myArray.length); //3

    【讨论】:

    • 我看不出这个解决方案有什么优雅之处,但无论如何@shoesel 已经发布了
    【解决方案7】:

    获取数组的最后一个元素:

    const [last,] = ['a', 'b', 'program'].reverse();
    

    【讨论】:

    • 我必须补充一点,JavaScript Array reverse 是就地完成的。所以这个解决方案可能不适合每个人,和/或存在性能问题。我被烧死了……
    【解决方案8】:

    这应该可行:

    const [lastone] = myArray.slice(-1);
    

    【讨论】:

      【解决方案9】:

      const arr = ['a', 'b', 'c']; // => [ 'a', 'b', 'c' ]
      
      const {
        [arr.length - 1]: last
      } = arr;
      
      console.log(last); // => 'c'

      【讨论】:

      • 是的,我发现它在已经进行其他解构时很有用。它本身并不像经典解决方案那样容易阅读。
      【解决方案10】:

      不是破坏方式,但可以提供帮助。根据javascript文档和反向方法可以试试这个:

      const reversed = array1.reverse();
      let last_item = reversed[0]
      

      【讨论】:

        【解决方案11】:
        let a = [1,2,3]
        let [b] = [...a].reverse()
        

        【讨论】:

          【解决方案12】:

          你可以试试这个技巧:

          let a = ['a', 'b', 'program'];
          let [last] = a.reverse();
          a.reverse();
          console.log(last);
          

          【讨论】:

            【解决方案13】:

            当然,问题是关于 JavaScript 数组的 Destructuring,我们知道使用解构赋值不可能拥有数组的最后一项,有一种方法可以做到这一点不可变 strong>,请参阅以下内容:

            const arr = ['a', 'b', 'c', 'last'];
            
            ~~~
            const arrDepth = arr.length - 1;
            
            const allExceptTheLast = arr.filter( (dep, index) => index !== arrDepth && dep );
            const [ theLastItem ] = arr.filter( (dep, index) => index === arrDepth && dep );
            

            我们不改变arr 变量,但仍然将除最后一项之外的所有数组成员作为一个数组,并且将最后一项分开。

            【讨论】:

              【解决方案14】:

              使用数组解构:“捕获”array、“spliced”数组(arrMinusEnd)和“poped”/“sliced”元素(endItem)。

              var [array, arrMinusEnd, endItem] = 
                ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"]
                .reduce(
                  (acc, cv, idx, arr) => {
                    if(idx<arr.length-1) acc[1].push(cv);
                    else {
                      acc[0]=arr;
                      acc[2]=cv;
                    };
                    return acc;
                  },
                  [null,[],[]]
                )
              ;
              
              console.log("array=");
              console.log(array);
              console.log("arrMinusEnd=");
              console.log(arrMinusEnd);
              console.log("endItem=\""+endItem+"\"");
              .as-console-wrapper { max-height: 100% !important; top: 0; }

              【讨论】:

                【解决方案15】:

                您可以进一步将数组的...rest 数组破坏为Object,以获取其length 属性并为最后一个索引构建computed prop name

                这甚至适用于参数销毁:

                const a = [1, 2, 3, 4];
                
                // Destruct from array ---------------------------
                const [A_first, ...{length: l, [l - 1]: A_Last}] = a;
                console.log('A: first: %o; last: %o', A_first, A_Last);     // A: first: 1; last: 4
                
                // Destruct from fn param(s) ---------------------
                const fn = ([B_first, ...{length: l, [l - 1]: B_Last}]) => {
                  console.log('B: first: %o; last: %o', B_first, B_Last);   // B: first: 1; last: 4
                };
                
                fn(a);

                【讨论】:

                  猜你喜欢
                  • 2017-11-15
                  • 2022-09-29
                  • 2020-02-22
                  • 1970-01-01
                  • 2011-09-09
                  • 2016-08-26
                  • 1970-01-01
                  • 1970-01-01
                  • 2016-09-29
                  相关资源
                  最近更新 更多