我有一个包含子数组的数组,类似于:
someArray = [[Bill, 1], [Ted, 2], [Steve, 2], [Alex, 3]]
我试图将每个子数组中的第一个值推入新数组中的次数与第二个值相同。因此,对于上面的示例,我希望它看起来像这样:
newArray = [Bill, Ted, Ted, Steve, Steve, Alex, Alex, Alex]
我可以使用这些嵌套的for
循环访问子数组中的值,但是据我所知:
for (var i=0, len=data.length; i<len; i++) {
// inner loop applies to sub-arrays
for (var j=0, len2=data[i].length; j<len2; j++) {
// accesses each element of each sub-array in turn
names.push(data[i][j]);
//adds each element to a new array
答案 0 :(得分:3)
您可以使用reduce
简洁地执行此操作,在每次迭代时将所需数量的项目推送到累加器:
const someArray = [['Bill', 1], ['Ted', 2], ['Steve', 2], ['Alex', 3]];
const output = someArray.reduce((a, [repeatItem, repeatCount]) => {
a.push(...Array.from({ length: repeatCount }, () => repeatItem));
return a;
}, []);
console.log(output);
无论子数组中第一项的数据类型如何,此方法均有效,但请注意,如果repeatItem
是对象 (或数组或函数),则将对同一对象具有多个引用,而不是对象的深层克隆。 (从该对象的每次引用中都可以看到该对象的一种变异)
答案 1 :(得分:1)
如果您想使用经过纠正且可以正常使用的解决方案本身,则可以查看下面的代码及其与自己的代码的区别:
var data = [["Bill", 1], ["Ted", 2], ["Steve", 2], ["Alex", 3]];
var names=[];
for (var i=0, len=data.length; i<len; i++)
for (var j=0; j<data[i][1]; j++)
names.push(data[i][0]);
console.log(names);
但是使用reduce
或map
函数会更时尚:
var someArray = [["Bill", 1], ["Ted", 2], ["Steve", 2], ["Alex", 3]];
var names=
Array.prototype.concat.apply(
[],
someArray.map(function(d){
var r=[], i=0;
for(;i<d[1];i++) r.push(d[0]);
return r;
})
);
console.log(names);
和reduce
版本:
var names=
someArray.reduce(function(a, d){
var i=0;
for(;i<d[1];i++) a.push(d[0]);
return a;
}, [])
console.log(names);
答案 2 :(得分:0)
@tdehnel,您使用的想法是正确的,只是没有正确执行。只是微小的变化,哥们。
len2
的长度不应为data[i]
,因为data[i].length
是
始终为2,因为每个子数组的长度为2。相反,您希望它
循环每个元素的第二个元素表示的次数
我认为是data[i][1]
。因此,len2 =
data[i][1]
。data[i][0]
而不是data[i][j]
。代码如下:
for (var i = 0, len = data.length; i < len; i++) {
// inner loop applies to sub-arrays
for (var j = 0, len2 = data[i][1]; j < len2; j++) {
// accesses each element of each sub-array in turn
names.push(data[i][0]);
//adds each element to a new array
否则,您可以按照@CertainPerformance的建议进行操作,这也是一种简单的方法。