【问题标题】:How can I reverse an array in JavaScript without using libraries?如何在不使用库的情况下反转 JavaScript 中的数组?
【发布时间】:2012-04-27 10:09:41
【问题描述】:

我正在使用arrays 按顺序保存一些数据,并且我想添加一个用户可以反转列表的功能。我想不出任何可能的方法,所以如果有人知道如何,请帮忙。

【问题讨论】:

标签: javascript arrays


【解决方案1】:
const original = [1, 2, 3, 4];
const reversed = [...original].reverse(); // 4 3 2 1

简明扼要,保持原样不变。

【讨论】:

    【解决方案2】:

    实际上reverse()在某些情况下可能不起作用,所以你必须先做一个做作如下

    let a = [1, 2, 3, 4];
    console.log(a);  // [1,2,3,4]
    a = a.reverse();
    console.log(a); // [4,3,2,1]
    

    或使用 concat

    let a = [1, 2, 3, 4];
    console.log(a, a.concat([]).reverse());  // [1,2,3,4], [4,3,2,1]
    

    【讨论】:

      【解决方案3】:

      两种方式:

      1. 计数器循环

        function reverseArray(a) { 
             var rA = []
             for (var i = a.length; i > 0; i--) {
                 rA.push(a[i - 1])
             } 
        
             return rA;
          }
        
      2. 使用 .reverse()

         function reverseArray(a) {  
             return a.reverse()  
          }
        

      【讨论】:

        【解决方案4】:

        我不确定库是什么意思,但这里是我能想到的最佳方式:

        // return a new array with .map()
        const ReverseArray1 = (array) => {
            let len = array.length - 1;
        
            return array.map(() => array[len--]);
        }
        
        console.log(ReverseArray1([1,2,3,4,5])) //[5,4,3,2,1]
        
        // initialize and return a new array
        const ReverseArray2 = (array) => {
            const newArray = [];
            let len = array.length;
        
            while (len--) {
                newArray.push(array[len]);
            }
        
            return newArray;
        }
        
        console.log(ReverseArray2([1,2,3,4,5]))//[5,4,3,2,1]
        
        // use swapping and return original array
        const ReverseArray3 = (array) => {
            let i = 0;
            let j = array.length - 1;
        
            while (i < j) {
                const swap = array[i];
                array[i++] = array[j];
                array[j--] = swap;
            }
        
            return array;
        }
        console.log(ReverseArray3([1,2,3,4,5]))//[5,4,3,2,1]
        
        // use .pop() and .length
        const ReverseArray4 = (array) => {
            const newArray = [];
        
            while (array.length) {
                newArray.push(array.pop());
            }
        
            return newArray;
        }
        console.log(ReverseArray4([1,2,3,4,5]))//[5,4,3,2,1]
        

        【讨论】:

          【解决方案5】:

          使用交换并返回原始数组。

          const reverseString = (s) => {
            let start = 0, end = s.length - 1;
            while (start < end) {
              [s[start], s[end]] = [s[end], s[start]]; // swap
              start++, end--;
            }
            return s;
          };
          
          console.log(reverseString(["s", "t", "r", "e", "s", "s", "e", "d"]));

          【讨论】:

            【解决方案6】:

            此函数适用于索引之间可能存在间隙的数组。

            function reverse( a ) {
                var b = [], c = [] ;
                a.forEach( function( v ) { b.push( v ) } ) ;
                a.forEach( function( v, i ) { c[i] = b.pop() } ) ;
                return c ;
            }
            
            var a= [] ; a[1] = 2 ; a[3] = 4 ; a[7] = 6 ; a[9] = 8 ;
            a = reverse( a ) ;
            var s = '' ;
            a.forEach( function( v, i ) { s += 'a[' + i + '] = ' + v + '  ' } ) ;
            console.log( s ) ;
            // a[1] = 8  a[3] = 6  a[7] = 4  a[9] = 2
            

            【讨论】:

              【解决方案7】:
              reveresed = [...array].reverse()
              

              【讨论】:

                【解决方案8】:

                我也遇到了同样的问题。谢谢你的这个问题。我做了如下sn-p的代码。它工作得很好。我用的是 ES6。

                const Array = ["a", "b", "c", "d"];
                let revArray = [].concat(Array).reverse();
                

                当我 console.log 时,我得到如下输出

                console.log(revArray)
                // output: ["d","c","b","a"]
                

                【讨论】:

                • 为什么将您的阵列命名为Array?它很容易与关键字混淆,并且将常规变量的第一个字母大写,虽然可能,但它违反了所有约定/最佳实践。为信号类等保留该概念。
                【解决方案9】:

                我们有 reverse() 函数来反转 JS 中的给定数组。

                var a = [7,8,9];
                a.reverse(); // 9 8 7
                
                function reverseArr(input) 
                {
                var ret = new Array;
                for(var i = input.length-1; i >= 0; i--) 
                {
                    ret.push(input[i]);
                }
                return ret;
                }
                

                【讨论】:

                  【解决方案10】:

                  使用 ES6 反转数组和子数组(就地)。

                  function reverse(array, i=0, j=array.length-1){
                    while (i < j){
                      [array[i], array[j]] = [array[j], array[i]];
                      ++i;
                      --j;
                    }
                  }
                  

                  【讨论】:

                    【解决方案11】:

                    通过变量交换(可变)原地反转

                    const myArr = ["a", "b", "c", "d"];
                    for (let i = 0; i < (myArr.length - 1) / 2; i++) {  
                        const lastIndex = myArr.length - 1 - i; 
                        [myArr[i], myArr[lastIndex]] = [myArr[lastIndex], myArr[i]] 
                    }
                    

                    【讨论】:

                      【解决方案12】:

                      Array.prototype.reverse() 是您完成这项工作所需的全部。见compatibility table

                      var myArray = [20, 40, 80, 100];
                      var revMyArr = [].concat(myArray).reverse();
                      console.log(revMyArr);
                      // [100, 80, 40, 20]

                      【讨论】:

                      • 美观、无损
                      • 需要注意的是concat将对象引用复制到新数组中。原始数组和新数组都引用同一个对象...
                      【解决方案13】:

                      使用 .pop() 方法和 while 循环。

                      var original = [1,2,3,4];
                      var reverse = [];
                      while(original.length){
                          reverse.push(original.pop());
                      }
                      

                      输出:[4,3,2,1]

                      【讨论】:

                        【解决方案14】:

                        也可以使用map方法实现。

                        [1, 2, 3].map((value, index, arr) => arr[arr.length - index - 1])); // [3, 2, 1]
                        

                        或者使用reduce(稍微长一点的方法)

                        [1, 2, 3].reduce((acc, curr, index, arr) => {
                            acc[arr.length - index - 1] = curr;
                            return acc;
                        }, []);
                        

                        【讨论】:

                          【解决方案15】:

                          下面是具有最佳空间和时间复杂度的解决方案

                          function reverse(arr){
                          let i = 0;
                          let j = arr.length-1; 
                          while(i<j){
                          arr[j] = arr[j]+arr[i];
                          arr[i] = arr[j] - arr[i];
                          arr[j] = arr[j] - arr[i];
                          i++;
                          j--;
                          }
                          return arr;
                          }
                          var arr = [1,2,3,4,5,6,7,8,9]
                          reverse(arr);
                          

                          输出 => [9,8,7,6,5,4,3,2,1]

                          【讨论】:

                            【解决方案16】:

                            **

                            不使用反向方法的最短反向数组方法:

                            **

                             var a = [0, 1, 4, 1, 3, 9, 3, 7, 8544, 4, 2, 1, 2, 3];
                            
                             a.map(a.pop,[...a]); 
                            // returns [3, 2, 1, 2, 4, 8544, 7, 3, 9, 3, 1, 4, 1, 0]
                            

                            a.pop 方法取出最后一个元素并使用扩展运算符 () 预先放置

                            MDN 链接供参考:

                            https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax

                            https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map

                            https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/pop

                            【讨论】:

                            • 同 Torkel Velure 的回答 [...a].map(a.pop,a)
                            【解决方案17】:

                            使用函数式编程来反转数组的纯函数:

                            var a = [3,5,7,8];
                            
                            // ES2015
                            function immutableReverse(arr) {
                              return [ ...a ].reverse();
                            }
                            
                            // ES5
                            function immutableReverse(arr) {
                              return a.concat().reverse()
                            }
                            

                            【讨论】:

                              【解决方案18】:

                              使用 ES6 的 rest 运算符和箭头函数。

                              const reverse = ([x, ...s]) => x ? [...reverse(s), x] : [];
                              reverse([1,2,3,4,5]) //[5, 4, 3, 2, 1]
                              

                              【讨论】:

                                【解决方案19】:

                                正如其他人提到的,您可以在数组对象上使用.reverse()

                                但是,如果您关心保留原始对象,您可以改用reduce

                                const original = ['a', 'b', 'c'];
                                const reversed = original.reduce( (a, b) => [b].concat(a) );
                                //                                           ^
                                //                                           |
                                //                                           +-- prepend b to previous accumulation
                                
                                // original: ['a', 'b', 'c'];
                                // reversed: ['c', 'b', 'a'];
                                

                                【讨论】:

                                  【解决方案20】:

                                  这个怎么样?

                                    function reverse(arr) {
                                      function doReverse(a, left, right) {
                                        if (left >= right) {
                                          return a;
                                        }
                                        const temp = a[left];
                                        a[left] = a[right];
                                        a[right] = temp;
                                        left++;
                                        right--;
                                        return doReverse(a, left, right);
                                      }
                                  
                                      return doReverse(arr, 0, arr.length - 1);
                                    }
                                  
                                    console.log(reverse([1,2,3,4]));
                                  

                                  https://jsfiddle.net/ygpnt593/8/

                                  【讨论】:

                                    【解决方案21】:

                                    我见过的最短的反向方法是这个:

                                    let reverse = a=>a.sort(a=>1)
                                    

                                    【讨论】:

                                    • 这不取决于排序是如何实现的吗?由于比较函数不一致(即它始终返回 1),因此行为未定义。
                                    • 实际上我很惊讶地看到它的工作方式。例如,[1,2,3,4].sort(a=&gt;1) 返回正确答案。这个想法是它与 sort 方法如何采用排序算法密切相关,并且由于它是一个接一个地执行的,所以它总是交换。
                                    • 这样做的问题是它可能无法使用不同的解释器反转数组。
                                    • 我并不是建议这是一种好的做法,只是认为这是对众所周知的操作的一种有趣、非传统的尝试。
                                    【解决方案22】:

                                    我只是将haskell实现重写为js。

                                    const rev = (list, reversed) => {
                                        if (list.length == 0) return reversed
                                    
                                        reversed.unshift(list[0])
                                        return rev(list.slice(1), reversed)
                                    }
                                    
                                    const reverse = (list) => rev(list, [])
                                    

                                    【讨论】:

                                    • 这种实现在 JS 中效率非常低,因为数组不是链表。
                                    【解决方案23】:

                                    使用排序方法进行逆向

                                    • 这是一种更简洁的方法。

                                    const resultN = document.querySelector('.resultN');
                                    const resultL = document.querySelector('.resultL');
                                    
                                    const dataNum = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
                                    const dataLetters = ['a', 'b', 'c', 'd', 'e'];
                                    
                                    const revBySort = (array) => array.sort((a, b) => a < b);
                                    
                                    resultN.innerHTML = revBySort(dataNum);
                                    resultL.innerHTML = revBySort(dataLetters);
                                    <div class="resultN"></div>
                                    <div class="resultL"></div>

                                    【讨论】:

                                    • 这种就地反转效率不高,排序方法不正确(不一致的比较函数具有实现定义的行为)。
                                    • 除了 Ry 提到的之外,考虑到可以在 O(n/2) 内完成就地更改,这是一种低效的方法,因为您只需要真正横向一半数组。排序函数的时间复杂度是 O(n log n),甚至比 O(n) 的解还要糟糕。
                                    【解决方案24】:

                                    你可以的

                                    var yourArray = ["first", "second", "third", "...", "etc"]
                                    var reverseArray = yourArray.slice().reverse()
                                    
                                    console.log(reverseArray)
                                    

                                    你会得到

                                    ["etc", "...", "third", "second", "first"]
                                    

                                    【讨论】:

                                    • 一个好的无损解决方案。请注意,slice 执行的是浅拷贝。
                                    【解决方案25】:

                                    20 字节

                                    let reverse=a=>[...a].map(a.pop,a)
                                    

                                    【讨论】:

                                    • 有人能帮我解释一下吗?
                                    • @user169320 [...a] 克隆数组,.map(a.pop, a) 弹出数组(返回数组的最后一个元素)并将其推送到新数组,从而产生一个反转数组。
                                    • ...和map 的第二个参数确保popa 作为this 一起执行,就像你已经完成a.pop() 一样
                                    • 当你传递一个函数引用(所以不执行它),它稍后用于执行,那么这个函数引用根本没有你想要的对象的跟踪让它执行:它只是一个普通的函数。在上面的代码中,您不妨使用[].pop 而不是a.pop:这将是完全 相同的功能。当map 的实现执行该函数时,它不知道应该在哪个数组上执行。如果你不告诉它,它就会失败。 map 的第二个参数将必要的信息提供给 map
                                    • 是 CodeGolf 吗?
                                    【解决方案26】:
                                    function reverseArray(arr) {
                                        let reversed = [];
                                        for (i = 0; i < arr.length; i++) { 
                                        reversed.push((arr[arr.length-1-i]))
                                        }
                                      return reversed;
                                    }
                                    

                                    【讨论】:

                                      【解决方案27】:

                                      53 字节

                                      function reverse(a){
                                          for(i=0,j=a.length-1;i<j;)a[i]=a[j]+(a[j--]=a[i++],0)
                                      }
                                      

                                      只是为了好玩,这里有一个比原生 .reverse 方法更快的替代实现。

                                      【讨论】:

                                        【解决方案28】:

                                        JavaScript 已经在 Array 上有 reverse() 方法,所以你不需要做那么多!

                                        假设你有下面的数组:

                                        var arr = [1, 2, 3, 4, 5];
                                        

                                        现在只需这样做:

                                        arr.reverse();
                                        

                                        结果如下:

                                        [5, 4, 3, 2, 1];
                                        

                                        但这基本上改变了原始数组,您可以编写一个函数并使用它来返回一个新数组,如下所示:

                                        function reverse(arr) {
                                          var i = arr.length, reversed = [];
                                          while(i) {
                                            i--;
                                            reversed.push(arr[i]);
                                          }
                                          return reversed;
                                        }
                                        

                                        或者像这样简单地改变 Array 的 JavaScript 内置方法:

                                        function reverse(arr) {
                                          return arr.slice().reverse();
                                        }
                                        

                                        你可以这样称呼它:

                                        reverse(arr); //return [5, 4, 3, 2, 1];
                                        

                                        如前所述,主要区别在于第二种方式,您不要触摸原始数组...

                                        【讨论】:

                                          【解决方案29】:

                                          这是一种实用的方法。

                                          const array = [1,2,3,4,5,6,"taco"];
                                          
                                          function reverse(array){
                                            return array.map((item,idx) => array[array.length-1-idx])
                                          }
                                          

                                          【讨论】:

                                          • 如果您不想更改 orig 数组,则解决方案非常简单!
                                          • 如果您正在编写纯函数或出于任何其他原因不想改变原始数组,这非常有用。
                                          【解决方案30】:

                                          我已经对解决方案进行了一些测试,这些解决方案不仅可以反转数组,还可以复制它。这是测试代码。 reverse2 方法是 Chrome 中最快的方法,但在 Firefox 中reverse 方法是最快的。

                                          var array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
                                          
                                          var reverse1 = function() {
                                            var reversed = array.slice().reverse();
                                          };
                                          
                                          var reverse2 = function() {
                                            var reversed = [];
                                            for (var i = array.length - 1; i >= 0; i--) {
                                              reversed.push(array[i]);
                                            }
                                          };
                                          
                                          var reverse3 = function() {
                                            var reversed = [];
                                            array.forEach(function(v) {
                                              reversed.unshift(v);
                                            });
                                          };
                                          
                                          console.time('reverse1');
                                          for (var x = 0; x < 1000000; x++) {
                                            reverse1();
                                          }
                                          console.timeEnd('reverse1'); // Around 184ms on my computer in Chrome
                                          
                                          console.time('reverse2');
                                          for (var x = 0; x < 1000000; x++) {
                                            reverse2();
                                          }
                                          console.timeEnd('reverse2'); // Around 78ms on my computer in Chrome
                                          
                                          console.time('reverse3');
                                          for (var x = 0; x < 1000000; x++) {
                                            reverse3();
                                          }
                                          console.timeEnd('reverse3'); // Around 1114ms on my computer in Chrome
                                          

                                          【讨论】:

                                            猜你喜欢
                                            • 1970-01-01
                                            • 2015-07-09
                                            • 1970-01-01
                                            • 2020-10-14
                                            • 1970-01-01
                                            • 1970-01-01
                                            • 1970-01-01
                                            • 1970-01-01
                                            相关资源
                                            最近更新 更多