简洁的方法是从另一个数组返回一个N个元素的新数组,这些数组中填充了迭代值?香草JavaScript

问题描述 投票:0回答:4

我有一个给定的数组,元素的数量不确定,该数组可以是数字或字符串,然后我需要根据第一个数组的迭代元素生成一个由N个元素组成的新数组

我已经有一个函数可以执行此操作,但是它仅在原始数组是连续数字时才有效,不适用于字符串。关于如何实现这一点,我有无数的想法。我可以将数组连接到一个新数组,直到其等于或大于所需的元素数量,然后将新的数组长度设置为所需的数量,但是有没有更简洁,更优雅的方法呢?

IDEA 01 codepen

function populateArray(qty) {
  // Array to populate from
  let array = [1,2,3];
  //Determine the Range Length of the array and assign it to a variable
  let min = array[0];
  let max = array[array.length - 1];
    const rangeLength = (max - min + 1);
    //Initialize uniqueArray which will contain the concatenated array
    let uniqueArray = [];
    //Test if quantity is greater than the range length and if it is,
    //concatenate the array to itself until the new array has equal number of elements or greater
    if (qty > rangeLength) {
        //Create an array from the expansion of the range
        let rangeExpanded = Array.from(new Array(rangeLength), (x,i) => i + min);
        while (uniqueArray.length < qty) {
            uniqueArray = uniqueArray.concat(rangeExpanded);
        }
    }
  // Remove additional elements
  uniqueArray.length = qty
    return uniqueArray;
}

console.log(populateArray(13))

IDEA 02 codepen,但是它用整个原始数组而不是迭代项填充了13次新数组

// FILL A NEW ARRAY WITH N ELEMENTS FROM ANOTHER ARRAY
let array = [1,2,3];
let length = 13;
let result = Array.from( { length }, () => array );

console.log(result);

预期结果为[1,2,3,1,2,3,1,2,3,1,2,3,1],如果原始数组由字符串组成,则预期结果将为[dog,cat ,绵羊,狗,猫,绵羊,狗,猫,绵羊,狗,猫,绵羊,狗]

javascript arrays
4个回答
2
投票
您可以稍微调整一下第二个想法-计算您需要重复初始数组以得出所需总数的项目,然后将其展平并.slice的次数:

let array = [1,2,3]; let length = 13; const fromLength = Math.ceil(length / array.length); let result = Array.from( { length: fromLength }, () => array ) .flat() .slice(0, length); console.log(result);

1
投票
您可以使用generator function,它将根据输入创建重复序列。您可以为生成的序列添加一个限制,然后将其转换为数组:

function* repeatingSequence(arr, limit) { for(let i = 0; i < limit; i++) { const index = i % arr.length; yield arr[index]; } } const generator = repeatingSequence(["dog", "cat", "sheep"], 10); const result = Array.from(generator); console.log(result);
或者,您可以无限地重复一个无限序列,然后为数组生成任意数量的元素:

function* repeatingSequence(arr) { let i = 0 while(true) { const index = i % arr.length; yield arr[index]; i++; } } const generator = repeatingSequence(["dog", "cat", "sheep"]); const result = Array.from({length: 10}, () => generator.next().value); console.log(result);

1
投票
我将使用@CertainPerformance的答案。但这是一种不同的方法,仅出于[[thing-out-of-the-box]]目的

// A function for getting an index up to length's size function getIDX(idx, length){ return idx <= length ? idx : getIDX(idx-length, length); } const newArrayLength = 13; const sourceArray = [1,2,3]; const resultArray = []; for(let i=0; i< newArrayLength; i++){ resultArray[i]=sourceArray[getIDX(i+1, sourceArray.length)-1]; }

编辑1
:我正在将这种方法与此处描述的其他方法的性能进行比较,似乎如果您想创建一个非常大的新数组(例如:newArrayLength = 10000),由于getIDX()函数的大小很大,调用堆栈。因此,我通过删除递归来改进了getIDX()函数,现在复杂度为O(1):[]

function getIDX(idx, length){ if (length === 1) {return idx}; const magicNumber = length * (Math.ceil(idx/length)-1); return idx - magicNumber; } 使用新的getIDX()函数,这种方法似乎是最有效的。您可以在此处查看测试:https://jsbench.me/v7k4sjrsuw/1

您可以使用modulo运算符:
Array.from({ length:length }, (e, i) => array[i] ? array[i] : array[ i % array.length ])

示例:

 

let array = [1,2,3]; let length = 13; const result = Array.from({ length:length }, (e, i) => array[i] ? array[i] : array[ i % array.length ]); console.log(result);

0
投票
© www.soinside.com 2019 - 2024. All rights reserved.