最后一项被推送到数组(Javascript)

最后一项被推送到数组(Javascript),javascript,Javascript,嗨,我有以下代码在我的项目。问题是最后一项被推送到数组中,而不是每个项 JS函数 函数getArrayObjForKeys(键、源、所需键){ 设arrayObj=[], obj={}; source.forEach(函数(val,ind){ 键。forEach(函数(v,i){ (职能(五){ 如果(val.hasOwnProperty(v)){ 设desKey=desiredKeys[i]; obj[desKey]=val[v]; } }).呼叫(本,v); }); arrayObj.p

嗨,我有以下代码在我的项目。问题是最后一项被推送到数组中,而不是每个项

JS函数


函数getArrayObjForKeys(键、源、所需键){
设arrayObj=[],
obj={};
source.forEach(函数(val,ind){
键。forEach(函数(v,i){
(职能(五){
如果(val.hasOwnProperty(v)){
设desKey=desiredKeys[i];
obj[desKey]=val[v];
}
}).呼叫(本,v);
});
arrayObj.push(obj);
});
返回arrayObj;
}
//调用函数如下
// **************************
变量源=[{
“国家”:“美国”,
“描述”:“美国”
}, {
“国家”:“英国”,
“描述”:“英国”
}];
var countryList=getArrayObjForKeys(['country','descr'],source,['value','label']);

控制台信息(国家列表)
您的问题是您在内存中引用了相同的
obj
,因此修改了这两个对象。解决这个问题的一个快速方法是将对象声明移动到
foreach
循环中,这样每个对象都有自己的唯一引用(不同)

请参见下面的工作示例:

函数getArrayObjForKeys(键、源、所需键){
设arrayObj=[]
source.forEach(函数(val,ind){
让obj={};/*移动到foreach中*/
键。forEach(函数(v,i){
(职能(五){
如果(val.hasOwnProperty(v)){
设desKey=desiredKeys[i];
obj[desKey]=val[v];
}
}).呼叫(本,v);
});
arrayObj.push(obj);
});
返回arrayObj;
}
变量源=[{
“国家”:“美国”,
“描述”:“美国”
}, {
“国家”:“英国”,
“描述”:“英国”
}];
var countryList=getArrayObjForKeys(['country','descr'],source,['value','label']);

控制台信息(国家列表)您可以使用reduce将源映射到所需输出,以将键、所需键和对象减少到新对象:

函数getArrayObjForKeys(键、源、所需键){
返回source.map(函数(obj){
返回键.reduce(函数(结果、键、索引){
结果[desiredKeys[index]=obj[key];
返回结果;
}, {});
});
}
var source=[{国家:'美国',描述:'美国'},{国家:'英国',描述:'英国'}];
var countryList=getArrayObjForKeys(['country','descr'],source,['value','label']);

控制台信息(国家列表)这里是另一种方法,使用
reduce
Object.entries
map

函数getArrayObjForKeys(键、源、所需键){
返回source.map(obj=>Object.entries(obj).reduce((累计,[key,val])=>{
const keyIdx=keys.indexOf(key);
累计[desiredKeys[keyIdx]]=val;
返回累计;
}, {}));
}
常量源=[
{‘国家’:‘美国’,‘描述’:‘美国’},
{‘国家’:‘英国’,‘描述’:‘联合王国}
];
const countryList=getArrayObjForKeys(['country','descr',source,['value','label']);

控制台信息(国家列表)使用ES6(并且假设两个输入数组始终具有相同的长度)的更简洁的替代方案是:

const getArrayObjForKeys=(keys,source,desiredKeys)=>source.map(obj=>{
让输出={};
keys.forEach((key,i)=>output[desiredKeys[i]]=obj[keys[i]]);
返回输出;
})
const source=[{'country':'USA','descr':'United'},{'country':'UK','descr':'United Kingdom'}],
countryList=getArrayObjForKeys(['country','descr',source,['value','label']);
控制台信息(国家列表)
更新foreach循环内的obj变量


问题在于obj变量

如果您想要更少的代码,这里有一个更具体的函数

易用功能(obj){
返回obj=obj.map(obj=>{
返回{“value”:obj.country,“lable”:obj.descr};
});
}
obj=[{
“国家”:“美国”,
“描述”:“美国”
}, {
“国家”:“英国”,
“描述”:“联合王国”
}];
obj=容易(obj);

控制台日志(obj)@ukb真棒!不用担心:)Object.entries不能保证以任何特定的顺序出现,因此您不应该以这种方式使用它。在这种情况下,这不是问题,因为我们正在从reduce函数输出一个对象,并且键也不能保证在对象中排序。所以输入是无序的,你是对的,但是输出并不依赖于输入的有序性。
getArrayObjForKeys(keys,source,desiredKeys){
    let arrayObj=[];
    source.forEach(function(val,ind){
    let obj={};
        keys.forEach(function(v,i){
          (function(v){
            if(val.hasOwnProperty(v)){
              let desKey = desiredKeys[i];
              obj[desKey] = val[v];
            }
          }).call(this, v);
        });
        arrayObj.push(obj);
    });
    return arrayObj;
  }