在 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()连接起来,对字符串进行变异,返回分割后的字符串。

注意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() );

【讨论】:

以上是关于在 JavaScript 中多次重复包含多个元素的数组的主要内容,如果未能解决你的问题,请参考以下文章

python selenium自动发送的整段信息被分割多次迭代重复发送?

C# LINQ 在列表中查找重复项

在 JavaScript 中重复一个字符串多次

Jquery根据用户输入选择包含多个类的元素[重复]

Javascript探索元素的孩子[重复]

多次引用数组中的元素并将该元素分配给变量[重复]