【问题标题】:Duplicate an array an arbitrary number of times (javascript)复制数组任意次数(javascript)
【发布时间】:2015-07-25 13:43:28
【问题描述】:

假设给了我一个数组。这个数组的长度是 3,并且有 3 个元素:

var array = ['1','2','3'];

最终我需要检查这个数组是否等于一个具有相同元素的数组,但现在只有两次。我的新数组是:

var newArray = ['1','2','3','1','2','3'];

我知道我可以使用 array.splice() 来复制一个数组,但是我怎样才能复制它未知的次数呢?基本上我想要的是具有

效果的东西
var dupeArray = array*2;

【问题讨论】:

  • 您想要一个函数来比较两个数组还是从给定数组生成一个新数组?
  • var arr=[1,2,3]; arr.map([].valueOf.bind(arr))
  • @Trott 我有一个比较两个数组元素的函数。我想我正在寻找的是一个函数,可以从给定的数组生成一个未知次数的新数组。
  • 在您复制的那一刻,您会知道要“复制”多少次,对吗?为什么不能多次使用 concat/splice/whatever?
  • 最终我需要检查这个数组是否等于具有相同元素的数组,但现在只有两次。这会不会是你的 XY 问题的 X ?换句话说,这是你的最终目标吗?

标签: javascript arrays node.js


【解决方案1】:

如果你在一个循环中,你可以用数组长度验证当前循环索引,然后乘以它的内容。

let arr = [1, 2, 3];

if(currentIndex > arr.length){ 
  //if your using a loop, make sure to keep arr at a level that it won't reset each loop

  arr.push(...arr);

}

完整示例: https://jsfiddle.net/5k28yq0L/

【讨论】:

    【解决方案2】:
    const duplicateArr = (arr, times) =>
        Array(times)
            .fill([...arr])
            .reduce((a, b) => a.concat(b));
    

    这应该可行。它创建一个新数组,其大小与您想要复制它的次数相同。它用数组的副本填充它。然后它使用 reduce 将所有数组连接成一个数组。

    【讨论】:

      【解决方案3】:

      基本但对我有用。

      var num = 2;
      
      while(num>0){
      array = array.concat(array);
      num--}
      

      【讨论】:

        【解决方案4】:

        这是一种相当简洁、非递归的任意次数复制数组的方法:

        function replicateArray(array, n) {
          // Create an array of size "n" with undefined values
          var arrays = Array.apply(null, new Array(n)); 
        
          // Replace each "undefined" with our array, resulting in an array of n copies of our array
          arrays = arrays.map(function() { return array });
        
          // Flatten our array of arrays
          return [].concat.apply([], arrays);
        }
        
        console.log(replicateArray([1,2,3],4)); // output: [1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3]
        

        发生了什么事?

        前两行使用apply 和map 创建数组的an array of "n" copies。

        最后一行使用applyto flatten我们最近生成的数组。

        说真的,发生了什么事?

        如果您没有使用过 apply 或 map,代码可能会令人困惑。

        这里的第一块魔法酱是使用apply(),它可以将数组传递给函数,就好像它是一个参数列表一样。

        Apply 使用三条信息:x.apply(y,z)

        • x 是被调用的函数
        • y 是函数被调用的对象(如果null,它使用global)
        • z为参数列表

        就代码而言,它转换为:y.x(z[0], z[1], z[2],...)

        例如

        var arrays = Array.apply(null, new Array(n));
        

        和写一样

        var arrays = Array(undefined,undefined,undefined,... /*Repeat N Times*/);
        

        第二个魔法是使用map(),它为数组的每个元素调用一个函数并创建一个返回值列表。

        这使用了两条信息:x.map(y)

        • x 是一个数组
        • y 是要在数组的每个元素上调用的函数

        例如

        var returnArray = [1,2,3].map(function(x) {return x + 1;});
        

        将创建数组 [2,3,4]

        在我们的例子中,我们传入了一个函数,该函数总是返回一个静态值(我们想要复制的数组),这意味着这个映射的结果是我们数组的 n 个副本的列表。

        【讨论】:

        • 棘手的代码,但要遵循它确实不容易。一方面,我更喜欢任何人都可以立即看到它的作用的代码。我的书中没有简洁的要点,但有一些要点是为了清晰、易于理解。
        • 很公平!我只是结合了 SO 的答案来展示如何查找子问题来构建复合答案。我会再分解一下。
        • 已更新并附有详细说明。唉,apply 和 map 可能只是一些高级概念,很难期望每个人都能一眼就明白。
        【解决方案5】:

        最简单的解决方案往往是最好的解决方案:

        function replicate(arr, times) {
             var al = arr.length,
                 rl = al*times,
                 res = new Array(rl);
             for (var i=0; i<rl; i++)
                 res[i] = arr[i % al];
             return res;
        }
        

        (或使用嵌套循环,例如@UsamaNorman)。

        不过,如果你想聪明一点,你也可以重复concat数组给自己:

        function replicate(arr, times) {
            for (var parts = []; times > 0; times >>= 1) {
                if (times & 1)
                    parts.push(arr);
                arr = arr.concat(arr);
            }
            return Array.prototype.concat.apply([], parts);
        }
        

        【讨论】:

        • 应该是res = new Array(rl); 虽然不是? i &lt; rl 在 for 循环中。不管我投了赞成票。
        【解决方案6】:

        保持简短和甜蜜

        function repeat(a, n, r) {
            return !n ? r : repeat(a, --n, (r||[]).concat(a));
        }
        
        console.log(repeat([1,2,3], 4)); // [1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3]
        

        http://jsfiddle.net/fLo3uubk/

        【讨论】:

        • 更短更甜:function replicate(a, n) { return !n ? [] : repeat(a, n-1).concat(a); }
        • @Bergi 太棒了!只是不要忘记用“复制”替换“重复”;-)
        【解决方案7】:

        你可以这样做:

        var array = ['1','2','3'];
        
        
        function nplicate(times, array){
              //Times = 2, then concat 1 time to duplicate. Times = 3, then concat 2 times for duplicate. Etc.
             times = times -1;
             var result = array;
        
            while(times > 0){
                result = result.concat(array);
                times--;
            }
        
            return result;
        }
        
        console.log(nplicate(2,array));
        

        你连接同一个数组 n 次。

        使用concat函数和一些逻辑:http://www.w3schools.com/jsref/jsref_concat_array.asp

        【讨论】:

        • 谢谢,现在可以了吗?我编辑了它。对不起这个错误。但我知道要创建一个函数来连接一个数组 n 次。
        【解决方案8】:

        检查它是否重复的相当粗略的解决方案...... 您可以使用模数检查长度的变化:

        如果可能的话,循环遍历内容并比较每个值直到完成。如果在任何时候它在结束前不匹配,那么它要么没有重复,要么在结束前停止重复。

        if (array2.length % array1.length == 0){
            // It might be a dupe
            for (var i in array2){
                if (i != array1[array2.length % indexOf(i)]) { // Not Repeating }
            }
        }
        

        【讨论】:

        • 当您使用“for var i in array2”语法时,您将遍历 array2 的索引。所以这个答案真的搞砸了。也许在这里使用 Array.prototype.forEach 会更优雅。使用模数是解决这个问题的好主意,所以我喜欢你的回答。
        【解决方案9】:

        我认为你必须编写自己的函数,试试这个:

        function dupArray(var n,var arr){
        var newArr=[];
        for(var j=0;j<n;j++)
            for(var i=0;i<arr.length;i++){
                newArr.push(arr[i]);
            }
        return newArr;
        }
        

        【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-12-11
        • 1970-01-01
        • 2016-08-29
        • 1970-01-01
        • 1970-01-01
        • 2020-01-02
        • 2010-10-17
        相关资源
        最近更新 更多