在 JavaScript 中多次重复包含多个元素的数组
Posted
技术标签:
【中文标题】在 JavaScript 中多次重复包含多个元素的数组【英文标题】:Repeat an array with multiple elements multiple times in 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 侧重于多次重复单个元素,而我想重复一个包含多个元素的数组。
使用维护良好的库是可以接受的。
【问题讨论】:
【参考方案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()连接起来,对字符串进行变异,返回分割后的字符串。
注意:IE
和 android 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() );
【讨论】:
以上是关于在 JavaScript 中多次重复包含多个元素的数组的主要内容,如果未能解决你的问题,请参考以下文章