对javascript上的数组感到困惑

对javascript上的数组感到困惑,javascript,arrays,Javascript,Arrays,我想在另外两个阵列的基础上创建下一个阵列: array1 = ['a', 'b'] array2 = [1,2,3] 我想创建下一个数组 newArray = [['a',1], ['a',2], ['a',3], ['b',1], ['b',2], ['b',3]] 这是我的密码: var test1=['a','b']; var test2=[1,2,3],arr1=[],arr2=[]; 对于(var i=0;i

我想在另外两个阵列的基础上创建下一个阵列:

array1 = ['a', 'b']
array2 = [1,2,3]
我想创建下一个数组

newArray = [['a',1], ['a',2], ['a',3], ['b',1], ['b',2], ['b',3]]
这是我的密码:

var test1=['a','b'];
var test2=[1,2,3],arr1=[],arr2=[];
对于(var i=0;i1)
arr1.pop();
arr1.push(test2[x])
arr2.推送(arr1);
}
}

log(“arr1:,JSON.stringify(arr1),“arr2:,JSON.stringify(arr2))您的方法有点错误,您最好采用这种方法(我认为这很简单):

var array1 = ['a', 'b'],
    array2 = [1,2,3],
    nextArray=[];

for(var i=0, array1Length=array1.length; i < array1Length; i++){
    for(var x=0, array2Length=array2.length; x < array2Length; x++){
    nextArray.push([array1[i],array2[x]]);
  }
}

console.log(nextArray);
var array1=['a','b'],
array2=[1,2,3],
nextArray=[];
对于(变量i=0,array1Length=array1.length;i
之所以发生这种情况,是因为一旦arr1的长度超过1,您就会将元素从arr1中弹出,所以最后一个元素就是所有持续存在的元素

试试这个:

var test1=['a','b'];
var test2=[1,2,3];
变量arr1=[],arr2=[];
对于(var i=0;ilog(JSON.stringify(arr1))每隔一个关于数组长度的答案,类似的事情是不对的。得到
3
(或者不管最后一个值/长度是什么)的唯一原因是数组是通过引用得到的,而
函数
,而不是
for循环
创建词法范围。这就是你听到“函数是javascript中的一流公民”的原因之一。这是一个经典的例子,在采访中也经常出现,它让不习惯javascript中作用域的开发人员感到困惑。有一些方法可以解决这个问题,包括在函数作用域中包装循环的内部,并传递索引,但我想建议一种更“以javascript为中心”的方法,即解决函数的问题

看看这个例子(顺便说一句,这也是实现你目标的一个明确方法。)

var test1=['a','b'];
var test2=[1,2,3];
//这将遍历数组1并返回
//[a,1],[a,2],[a,3],[b,1],[b,2],[b,3]]
var merged=test1.map(函数(item1){
返回test2.map(函数(item2){
返回[项目1,项目2];
});	
});
//这是一种“扁平化”结果集的巧妙方法
var answer=[].concat.apply([],合并)

console.log(answer)//就是这样。
我对您的代码做了一些修改(但不是太多,我尝试保持相同的方法)。解决方案是在内部循环中创建一个新数组(
arr1
)。否则,第一对正确的
['a',1]
将在下一个循环过程中将begin推送到
arr2
后立即被覆盖

var test1 = ['a', 'b'];
var test2 = [1,2,3];
var arr2 = [];

for(var i = 0; i < test1.length; i++){
    for(var x = 0; x < test2.length; x++){
        var arr1 = [];
        arr1.push(test1[i]);

        if(arr1.length > 1){
           arr1.pop();
        }
        arr1.push(test2[x]);
        arr2.push(arr1);
    }
}
var test1=['a','b'];
var test2=[1,2,3];
var arr2=[];
对于(var i=0;i1){
arr1.pop();
}
arr1.push(test2[x]);
arr2.推送(arr1);
}
}

您的问题在于第二个循环。因为您只有一个对ary1的引用,所以在每个循环中都过度写入了值

所以,当它第一次循环时,您的数组将

[['a',1]]
但是,因为您只有一个对ary1的引用,所以您只是在编辑刚刚压入ary2的值

那么你得到这个:

[['a',2],['a',2]]

你可能认为你正在推一个新的数组,但事实上它是完全相同的数组!所以这个模式继续下去,你会得到你所看到的结果。

是的,这比它需要的要复杂得多。您想要的结果称为,可以如下生成:
const cartesianProduct=(a,b)=>{
常数rv=[];
a、 map(ae=>b.map(be=>rv.push([ae,be]));
返回rv;
};
常量数组1=['a','b']
常量数组2=[1,2,3]

log(JSON.stringify(cartesianProduct(array1,array2))除了两个数组的固定样式解决方案之外,您还可以使用另一种方法来获得结果。您可以使用迭代和递归方法来处理零件的可变长度及其长度

函数组合(数组){
功能c(部分,索引){
数组[index].forEach(函数(a){
var p=部分混凝土([a]);
if(p.length==array.length){
r、 推(p);
返回;
}
c(p,指数+1);
});
}
var r=[];
c([],0);
返回r;
}
log(combine(['a',b'],[1,2,3]]);
log(组合(['a','b','c'],['1','2','3','4'],['a','b']]);
log(组合(['a',b',c'],['1',2',3',4'],['a'],['b']])

.as console wrapper{max height:100%!important;top:0;}
我想正确的功能方法应该是使用一个线性reduce和嵌套map duo

var arr=['a','b'],
brr=[1,2,3],
结果=arr.reduce((p,c)=>p.concat(brr.map(e=>[c,e]),[]);

log(JSON.stringify(result))返回[item1,item2]
以按OP的要求创建数组?让我仔细检查一下,看起来是的,我的小提琴中有这个,正在编辑。现在更新了。看起来我把它们翻了个底朝天。工作演示和答案应该是正确的。@J.D.Pace有趣的是,如果你好奇的话,lodash的表现通常会优于native.map。很好的库,甚至有一个.flatte()函数来避免使用这种巧妙的展平技巧-更容易阅读。我推荐用lodash来做这种材料operation@the_5imian我已经为其他项目研究了lodash。也许是时候重温一下了。查看中的语法