【问题标题】:Fastest way to move first element to the end of an Array将第一个元素移动到数组末尾的最快方法
【发布时间】:2013-12-21 13:21:09
【问题描述】:

我想知道在 JavaScript 中将元素从 Array 的开头移动到结尾的最快方法是什么。例如,如果我们有

[8,1,2,3,4,5,6,7]

我们想要:[1,2,3,4,5,6,7,8]

我想将第一个元素移到末尾。我正在考虑将元素 0 与元素 1 切换,然后将元素 1 与元素 2 切换,依此类推,直到 8 位于 and (基本上是冒泡排序的工作原理)。我想知道是否有更快的方法将第一个元素带到最后。

我将使用小型数组(大约 10 个元素),并且我想避免使用 shift(),因为它非常慢。

这就是我现在在 chrome 上所拥有的,它比普通 shift+push 快 45%:http://jsperf.com/shift-myfunc

数组中将包含用于游戏的对象。

【问题讨论】:

  • 很遗憾 OP 如何寻找 fastest 方式而不仅仅是 a 并且人们给出一般性答案而没有解释为什么他们更快/比替代品慢。我猜是FGITW。 OP,您的具体用例是什么?你的目标是什么浏览器?数组有多大(它们总是 ~8 个元素吗?它们是 10K 元素吗?),如果你想要真正的基准测试,你需要更加具体。
  • 感谢编辑澄清 - 下一轮:它们是像 [1,2,,,5,8] 那样稀疏的数组还是它们总是满(就像你的例子),它们总是只包含整数吗?您的目标浏览器/引擎是什么?您每秒最多需要进行多少次此类转换的迭代?
  • @BenjaminGruenbaum 如果 OP 事先说明他们尝试了什么并且可能没有一般性的答案,那将会有所帮助。有问题的努力=回答的努力。使用 JSPerf 进行简单的测试会很好。 :)
  • @epascarello True - fastest 做某事的方式在这里非常依赖于目标 JS 引擎、数组大小、它包含的内容等等 - 我'我还在等待被说服 OP 真的需要它那么快并且需要付出什么代价(例如,如果他经常旋转,那么将数组的副本连接到自身并对其进行切片可能会很好,使用类型化数组或使用其他有用的技巧)。我知道 you 和 j08691 绝对是这里的好人,因为他们知道你的许多其他答案,但鉴于模棱两可,回答一个似乎毫无意义。

标签: javascript arrays element


【解决方案1】:

使用 shift() 和 push() 函数:

var ary = [8,1,2,3,4,5,6,7];
ary.push(ary.shift());  // results in [1, 2, 3, 4, 5, 6, 7, 8] 

例子:

var ary = [8,1,2,3,4,5,6,7];

console.log("Before: " + ary);

ary.push(ary.shift());  // results in [1, 2, 3, 4, 5, 6, 7, 8] 

console.log("After: " + ary);

【讨论】:

  • 对于任何未来的绕过者,它的工作原理是使用 Shift 功能。它删除数组中的第一项,然后将其返回。换句话说,这段代码删除了数组中的第一项,然后再次添加它——使其进入数组的底部。
  • 漂亮优雅。
  • 做得很好...我一直在寻找相反的结果,但想出了这个答案,所以经过一些快速研究后,这里是执行上述操作的相反方式... ary.unshift(ary.pop ());
【解决方案2】:

使用shiftpush

var a = ["a","b","c"];
var b = a.shift();
a.push(b);

var b = a.shift();
a[a.length] = b;

根据更新的问题进行编辑

什么是最快的?真的取决于数组的内容和浏览器/版本!

现在有什么方法可以删除第一个索引?

  • shift()
  • splice()
  • slice()

现在有哪些方法可以添加到最后一个索引?

  • push()
  • array[array.length]
  • concat() -- 甚至不打算尝试

其他方式

  • for 循环 - 创建新数组 [在大型数组上会很糟糕]

JSPerf:

http://jsperf.com/test-swapping-of-first-to-last


真正最快的是什么?

什么是最快的实际上取决于你对数组做什么。如果您只是使用第一个索引,那么让您的代码读取索引而不移动值将是最快的。如果您正在使用所有索引,则不仅仅是循环遍历,当您到达终点时,从零开始。基本计数器。

【讨论】:

  • 我想避免使用 shift 因为它很慢。
  • 不如在你的问题中这么说!
  • @user2815780 - 也许您应该在问题中发布您已经尝试过的内容,包括统计数据以显示什么是快什么是慢?
  • 我用方法和 JSPerf 更新了我的答案。我确信我的循环答案可以改进,我只是把它放在一起作为我实际工作的休息时间。
  • 请注意 splice() 返回一个数组,因此名为“splice-push”(我个人偏好)的测试并非 100% 正确。应该是:var b = arr.splice(0, 1); arr.push(b[0]);
【解决方案3】:

这是一个甜蜜的 ES6 版本

let arr = [1,2,3,4,5,6]

const [first, ...rest] = arr;
arr = [...rest,first]

【讨论】:

  • 真的很甜蜜
【解决方案4】:

使用拼接获取第一个元素

var first = array.splice(0,1);

如果是最后一个,则推入。

既然splice方法的返回值是一个数组,那不得不说

array.push(first[0]);

这里的工作示例:JSFIDDLE

【讨论】:

    【解决方案5】:

    以防万一你想把任何元素放在最后:

    var ary = [8,1,2,3,4,5,6,7];
    ary.push(ary.splice(position, 1)[0]);
    

    对于position,只需将其包装在 forEach 中即可。

    【讨论】:

    • ary.push(ary.slice(position, 1)); 是错误的,如果 position 为 0,将导致 [8,1,2,3,4,5,6,7,Array[1],如果 position 为 1,将导致 [8,1,2,3,4,5,6,7,Array[0]。我假设您想要 splice 而不是 slice。因为slice 不会删除项目,它使用参数列表start, end 而不是start, deleteCount。无论哪种方式,切片/拼接都返回一个数组,因此您必须推送 arr 的第一项,而不是 arr 本身。我修复了代码:ary.push(ary.splice(0, 1)[0]);
    【解决方案6】:
    var a = [1,2,3,4,5,6,7,8];
    var b= a[7];
    var c = a.slice(1, 8);
    c.push(b);
    

    编辑: 像 epascarello 在his answer 中所做的那样,换班可能会更好。

    【讨论】:

      【解决方案7】:

      使用 ES20...

      const newArr = [
         ...arr.slice(1),
         arr[0]
      ];
      

      【讨论】:

        【解决方案8】:

        另一种味道

        var arr = [0, 1, 2];
        arr = arr.concat(arr.shift())
        

        concat 不仅可以添加一个元素,还可以在末尾或开头添加另一个数组

        【讨论】:

          【解决方案9】:

          更新数组,将元素从一个极端移动到另一个极端:

          const array = ['First', 'Second', 'Third', 'Fourth'];
          
          const next = [...array]
          next.push(next.shift())
          console.log(next); // [ 'Second', 'Third', 'Fourth', 'First' ]
          
          const prev = [...array]
          prev.unshift(prev.pop())
          console.log(prev); // [ 'Fourth', 'First', 'Second', 'Third' ]
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-12-19
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-10-10
            • 2021-09-09
            相关资源
            最近更新 更多