从属性数组和匹配 属性 值数组创建 JavaScript 对象的有效方法

efficient way to create JavaScript object from array of properties and array of matching property values

是否可以在不使用嵌套 for 循环的情况下创建 data1 数组?

// My starting Normalized data
var fields = ["name","age"];
var data2 = [["John",20],["Tom",25]]; 


// What I want the result to look like Denormalized
var data1 = [{"name":"John", "age":20},{"name":"Tom", "age":25}];


// My solution
var data1 = [];
for(var i = 0; i < data2.length; i++){
   var temp = {};
   for(var y = 0; y < fields.length; y++){
      temp[fields[y]] = data2[i][y];
   }
   data1.push(temp);
}

您可以使用map and forEach

var fields = ["name","age"];
var data2 = [["John",20],["Tom",25]]; 
var data1 = data2.map(function(arr){ 
   var obj = {};
   arr.forEach(function(val, ind){ obj[fields[ind]] = val; });
   return obj;
});

但它基本上是嵌套循环。

或者您可以开始熟悉 Javascript 工具,例如 underscore/lodash 库,这些库为此类情况提供了很多实用功能。

例如,使用_.zipObject() offered by lodash:

fields = ["name", "age"];
data2 = [["John", 20],["Tom", 25]];
res = [];
data2.forEach(function(arr) {
    res.push(_.zipObject(fields, arr));
});

正如@epascarello 提到的那样,本质上,您仍在进行双循环。它只是更优雅(始终取决于编码品味)和更紧凑。

没有循环...

var data1 = [];
data1.push(eval('({"' + fields[0] + '":"' + data2[0][0] +
                '","' + fields[1] + '":' + data2[0][1] + '})'));
data1.push(eval('({"' + fields[0] + '":"' + data2[1][0] +
                '","' + fields[1] + '":' + data2[1][1] + '})'));

猜猜这取决于你对高效的定义。

另一个使用原生 map 和 reduce 的实现(这将是嵌套循环 - 但我想我会把它作为另一个选项):

var data1 = data2.map(function(currentArray, index){
  return currentArray.reduce(function(objToReturn, currentValue, index){
    objToReturn[fields[index]] = currentValue;
    return objToReturn;
  },{});
});

终于想到不用nest for循环的高效方法了! :)

var fields = ["name","age"];
var data2 = [["John",20],["Tom",25]]; 
var body = "";

for(var i = 0; i < fields.length; i++){
   body = body.concat("this."+fields[i] +"=args["+i+"]; ");
}

var model = new Function("args",body);

var data1 = [];
for(var i = 0; i < data2.length; i++){
   var x = new model(data2[i]);
   data1.push(x);
}