从另一个数组返回一个N个元素的新数组的简便方法,该数组填充了迭代值?香草JavaScript [英] Concise way to return a new array of N elements filled with iterated values from another array? Vanilla JavaScript

查看:51
本文介绍了从另一个数组返回一个N个元素的新数组的简便方法,该数组填充了迭代值?香草JavaScript的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a given array with an undetermined quantity of elements, the array can be numbers or strings, then I need to generate a new array of N elements made from the iterated elements of the first array

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

I already have a function to do it, but it only works if the original array are consecutive numbers, it doesn't work with strings. I have a gazillion of ideas on how to achieve it. I could just concatenate the array to a new one until its equal or greater than the required quantity of elements, and then set the new array length to the required quantity, but is there a more concise and elegant way to do it?

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次新数组,而不是重复的项目

IDEA 02 codepen, but it fills the new array 13 times with the whole original array, not iterated items

// 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,猫,绵羊,狗,猫,绵羊,狗,猫,绵羊,狗,猫,绵羊,狗]

the expected result is [1,2,3,1,2,3,1,2,3,1,2,3,1] if the original array were made of strings the expected result would be [dog,cat,sheep,dog,cat,sheep,dog,cat,sheep,dog,cat,sheep,dog]

推荐答案

我将使用@CertainPerformance的答案.但是,这是另一种方法,仅用于开箱即用的目的

I'll go with @CertainPerformance's answer. But here's a different approach, just for thinking-out-of-the-box purposes

// 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):

EDIT 1: I was comparing the performance of this approach versus the others here described and it seems that if you wanted to create a very large new array (ex: newArrayLength= 10000) the getIDX() function takes a lot to finish because of the size of the call stack. So I've improved the getIDX() function by removing the recursion and now the complexity is O(1) check it out:

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

With the new getIDX() function this approach seems to be the most performant. You can take a look to the tests here: https://jsbench.me/v7k4sjrsuw/1

这篇关于从另一个数组返回一个N个元素的新数组的简便方法,该数组填充了迭代值?香草JavaScript的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆