簡體   English   中英

返回一個由另一個數組中的迭代值填充的 N 個元素的新數組的簡潔方法? 原生 JavaScript

[英]Concise way to return a new array of N elements filled with iterated values from another array? Vanilla JavaScript

我有一個給定的元素數量不確定的數組,該數組可以是數字或字符串,然后我需要生成一個由第一個數組的迭代元素組成的 N 個元素的新數組

我已經有一個函數可以做到這一點,但它只適用於原始數組是連續數字,它不適用於字符串。 關於如何實現它,我有無數的想法。 我可以將數組連接到一個新的數組,直到它等於或大於所需的元素數量,然后將新的數組長度設置為所需的數量,但是有沒有更簡潔優雅的方法來做到這一點?

IDEA 01代碼筆

 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,sheep ,狗,貓,羊,狗,貓,羊,狗,貓,羊,狗]

您可以稍微調整您的第二個想法 - 計算您需要重復初始數組的次數以得出所需的總項目數,然后將其展.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);

您可以使用生成器函數從輸入創建重復序列。 您可以為生成的序列添加一個限制,並將其簡單地轉換為一個數組:

 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);

我會選擇@CertainPerformance 的回答。 但這是一種不同的方法,只是為了開箱即用的目的

// 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()函數,這種方法似乎是最getIDX() 您可以在此處查看測試: https : //jsbench.me/v7k4sjrsuw/1

您可以使用modulo運算符。 特別感謝@Vlaz的縮短版本:

Array.from({ length:length }, (e, i) => array[ i  % array.length ])

一個例子:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM