【问题标题】:Repeat an array with multiple elements multiple times in JavaScript在 JavaScript 中多次重复包含多个元素的数组
【发布时间】:2018-11-13 06:57:30
【问题描述】:

在 JavaScript 中,如何以简洁的方式重复包含多个元素的数组?

在 Ruby 中,你可以这样做

irb(main):001:0> ["a", "b", "c"] * 3
=> ["a", "b", "c", "a", "b", "c", "a", "b", "c"]

我查找了 lodash 库,但没有找到任何直接适用的内容。 Feature request: repeat arrays. 是将其添加到 lodash 的功能请求,最好的解决方法是

const arrayToRepeat = [1, 2, 3];
const numberOfRepeats = 3;
const repeatedArray = _.flatten(_.times(numberOfRepeats, _.constant(arrayToRepeat)));

问题Most efficient way to create a zero filled JavaScript array?Create an array with same element repeated multiple times 侧重于多次重复单个元素,而我想重复一个包含多个元素的数组。

使用维护良好的库是可以接受的。

【问题讨论】:

    标签: javascript arrays repeat


    【解决方案1】:

    不需要任何库,你可以使用Array.from创建一个你想要重复的数组,然后使用[].concat进行展平并传播:

    const makeRepeated = (arr, repeats) =>
      [].concat(...Array.from({ length: repeats }, () => arr));
      
    console.log(makeRepeated([1, 2, 3], 2));

    在较新的浏览器上,您可以使用Array.prototype.flat 而不是[].concat(...

    const makeRepeated = (arr, repeats) =>
      Array.from({ length: repeats }, () => arr).flat();
      
    console.log(makeRepeated([1, 2, 3], 2));

    【讨论】:

    • 如果repeats参数改成length可以让代码更简洁:p
    • 我最初是这样做的,但我认为它使意图不太清楚
    【解决方案2】:

    您可以使用Array 构造函数及其fill 方法将您要重复的数组填充多次,然后concat 将它们(子数组)填充到单个数组中:

    const repeatedArray = [].concat(...Array(num).fill(arr));
    

    注意:在较旧的浏览器(ES6 之前)上,您可以使用 Function#apply 来模仿上面的其余语法(concat 将被调用,每个子数组都传递给它论点):

    var repeatedArray = [].concat.apply([], Array(num).fill(arr));
    

    示例:

    const arrayToRepeat = [1, 2, 3];
    const numberOfRepeats = 3;
    
    const repeatedArray = [].concat(...Array(numberOfRepeats).fill(arrayToRepeat));
    
    console.log(repeatedArray);

    【讨论】:

      【解决方案3】:

      const repeat = (a, n) => Array(n).fill(a).flat(1)
      
      console.log( repeat([1, 2], 3) )

      递归替代:

      const repeat = (a, n) => n ? a.concat(repeat(a, --n)) : [];
      
      console.log( repeat([1, 2], 3) )

      【讨论】:

        【解决方案4】:

        我的第一个想法是创建一个这样的函数

        let repeat = (array, numberOfTimes) => Array(numberOfTimes).fill(array).reduce((a, b) => [...a, ...b], [])
        console.log(repeat(["a", "b", "c"], 3))

        使用fill 方法和reduce

        理想情况下,您可以使用flatten,而不是使用reduce,但浏览器尚不支持

        【讨论】:

        • 已编辑 - 为该案例添加了默认值
        【解决方案5】:

        不幸的是,在 JS 中是无法原生实现的(也无法实现运算符重载,所以我们不能使用 Array.prototype.__mul__ 之类的东西),但我们可以创建一个具有适当目标长度的 Array,填充占位符,然后重新-映射值:

        const seqFill = (filler, multiplier) => 
          Array(filler.length * multiplier)
          .fill(1)
          .map(
            (_, i) => filler[i % filler.length]
          );
        
        console.log(seqFill([1,2,3], 3));
        console.log(seqFill(['a','b','c', 'd'], 5));

        或者通过挂钩到 Array 原型的另一种方式,您可以使用 Array#seqFill(multiplier) 的语法,这可能是您可以获得的最接近 ruby​​ 语法的语法(rb 基本上可以通过运算符重载完成所有操作,但 JS 不能) :

        Object.defineProperty(Array.prototype, 'seqFill', {
          enumerable: false,
          value: function(multiplier) {
            return Array(this.length * multiplier).fill(1).map((_, i) => this[i % this.length]);
          }
        });
        
        console.log([1,2,3].seqFill(3));

        【讨论】:

          【解决方案6】:

          除了显而易见的[].concat + Array.from({length: 3}, …)/fill() 解决方案之外,使用生成器将带来优雅的代码:

          function* concat(iterable) {
              for (const x of iterable)
                  for (const y of x)
                      yield y;
          }
          function* repeat(n, x) {
              while (n-- > 0)
                  yield x;
          }
          
          const repeatedArray = Array.from(concat(repeat(3, [1, 2, 3])));
          

          您也可以将其缩短为

          function* concatRepeat(n, x) {
              while (n-- > 0)
                  yield* x;
          }
          
          const repeatedArray = Array.from(concatRepeat(3, [1, 2, 3]));
          

          【讨论】:

            【解决方案7】:

            虽然其他方法很简单,但这些方法也很简单。

            Array.fill()Array.from() 之前的方法在 IE 中不起作用。 MDN Docs for Reference

            方法 1:循环并将 (Array.prototype.push) 相同的内容推送到数组中。

            function mutateArray(arr,n)
            {
                var temp = [];
                while(n--) Array.prototype.push.apply(temp,arr);
                return temp;
            }
            var a = [1,2,3,4,5];
            console.log(mutateArray(a,3));

            方法二:将数组元素和String.repeat()连接起来,对字符串进行变异,返回分割后的字符串。

            注意IEAndroid webviews 尚不支持 repeat 方法。

            function mutateArray(arr,n)
            {
                var arr = (arr.join("$")+"$").repeat(n).split("$");
                arr.pop(); //To remove the last empty element
                return arr;
            }
            var a = [1,2,3,4,5];
            console.log(mutateArray(a,3));

            【讨论】:

              【解决方案8】:

              试试

              Array(3).fill(["a", "b", "c"]).flat()
              

              console.log( Array(3).fill(["a", "b", "c"]).flat() );

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2020-10-20
                • 1970-01-01
                • 2018-06-15
                • 2015-06-07
                • 2021-12-23
                • 1970-01-01
                • 1970-01-01
                • 2019-05-30
                相关资源
                最近更新 更多