在JavaScript

时间:2018-06-04 00:19:53

标签: javascript arrays repeat

在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侧重于多次重复单个元素,而我想重复一个包含多个元素的数组。

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

8 个答案:

答案 0 :(得分:16)

不需要任何库,您可以使用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));

答案 1 :(得分:14)

您可以使用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);

答案 2 :(得分:9)

递归替代方案:



const repeat = (a, n) => n-- ? a.concat(repeat(a, n)) : [];

console.log( repeat([1, 2], 3) )




答案 3 :(得分:7)

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

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

使用fill方法和reduce

理想情况下,您可以使用flatten而不是使用reduce,但在浏览器中仍然没有支持

答案 4 :(得分:1)

不幸的是,它本身不可能在JS中(也不可能运算符重载,所以我们不能使用像Array.prototype.__mul__这样的东西),但我们可以创建一个具有适当目标长度的数组,填充占位符,然后重新映射值:

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));

答案 5 :(得分:1)

除了显而易见的[].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]));

答案 6 :(得分:1)

尽管其他方法很简单,但这些方法也是如此。

先前方法中的

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));

方法2 :将数组元素和String.repeat()连接起来以使字符串变异并返回分割后的字符串。

注意repeatIE中尚不支持Android webviews方法。

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));

答案 7 :(得分:1)

尝试

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

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