在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侧重于多次重复单个元素,而我想重复一个包含多个元素的数组。
使用维护良好的库是可以接受的。
答案 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))
理想情况下,您可以使用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()连接起来以使字符串变异并返回分割后的字符串。
注意:repeat
和IE
中尚不支持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() );