javascript 通过循环另一个数组中的值来创建指定长度的新数组

nsc4cvqm  于 2023-05-16  发布在  Java
关注(0)|答案(3)|浏览(185)

怎样才能达到以下效果?
在输入数字5和以下数组时:

const list = ['a', 'b', 'c'];

它应该产生以下输出:

['a', 'b', 'c', 'a', 'b'] // Total 5

我尝试了for和while,但我不知道当循环超过列表长度时如何重新启动循环。

qgzx9mmu

qgzx9mmu1#

计算整个列表重复多少次才能有足够的元素; do that repetition using Array.fill and .flat;然后truncate using .slice

function repeatToLength(source, size) {
    const iterations = Math.ceil(size / source.length);
    return Array(iterations).fill(source).flat().slice(0, size);
}

console.log(repeatToLength(['a', 'b', 'c'], 5));
szqfcxe2

szqfcxe22#

您可以通过从起始列表(下面的baseList)中重复添加项目,直到达到所需的长度。
你可以通过使用模运算符(%)来获得基列表中的正确索引,以获得输出列表的长度除以基列表的长度的余数,例如:

outputLength % baseLength == indexIntoBaseList
0 % 3 == 0
1 % 3 == 1
2 % 3 == 2
3 % 3 == 0
4 % 3 == 1
5 % 3 == 2

这为您的基本列表提供了一个重复的索引模式,您可以使用它来添加正确的项。

function RepeatListToLength(baseList, maxLength) {
    var output = [];
    while(output.length < maxLength) {
        output.push(baseList[output.length % baseList.length]);
    }
    return output;
}

console.log(RepeatListToLength([1,2,3,4,5], 13));
csbfibhn

csbfibhn3#

这是一个递归的变体。repeatToLength函数用一个由两个旧数组组成的新数组调用自己,直到它达到足够的长度,然后将最终数组切片到所需的确切长度:

const repeatToLength = (arr, len) => arr.length < len ?
  repeatToLength([...arr, ...arr], len) : arr.slice(0, len);

console.log(repeatToLength(['a', 'b', 'c'], 5));

我的第二个解决方案

在我的递归解决方案和Karls之间做了一些速度测试之后,我想我又给予了一次,写了一个版本,创建一个大的空数组,然后使用原始数组和模运算符Map它。(我从尼克的答案中偷了模数的概念。)
它比Chrome中的递归解决方案稍微快一点,在Firefox中更快一点(在Firefox中仍然没有击败Karls解决方案的速度):

const repeatToLength = (arr, len) => [...new Array(len)]
  .map((x, i) => arr[i % arr.length]);

console.log(repeatToLength(['a', 'b', 'c'], 5));

速度对比:我的两个算法和卡尔斯

我的在Chrome中似乎要快一些,但Karls在Firefox中稍快一些(MacOS -最新浏览器版本,2023年5月)。

  • 警告:* 此速度比较测试可能需要几秒钟才能运行,具体取决于您的CPU速度和浏览器。
const thomas = (arr, len) => arr.length < len ?
  thomas([...arr, ...arr], len) : arr.slice(0, len);

function karl(source, size) {
  const iterations = Math.ceil(size / source.length);
  return Array(iterations).fill(source).flat().slice(0, size);
}

const thomas2 = (arr, len) => [...new Array(len)]
  .map((x, i) => arr[i % arr.length]);

function time(func, args, runNumberOfTimes) {
  let start = performance.now();
  for (let i = 0; i < runNumberOfTimes; i++) {
    func(...args);
  }
  return Math.round(performance.now() - start) + ' ms';
}

let args;

console.log('Small array big repeat, run 2,000 times each');
args = [[1, 2, 3, 4, 5], 10000];
console.log('Array size: 5, make an array 10,000 items long.');
console.log('Karls solution', time(karl, args, 2000));
console.log('Thomas solution', time(thomas, args, 2000));
console.log('Thomas2 solution', time(thomas2, args, 2000));

console.log('\nBig array, smaller repeat, run 100 times each');
console.log('Array size: 10,000, make an array 100,000 items long');
args = ['x'.repeat(10000).split(''), 100000];
console.log('Karls solution', time(karl, args, 100));
console.log('Thomas solution', time(thomas, args, 100));
console.log('Thomas2 solution', time(thomas2, args, 100));

相关问题