【问题标题】:efficient way to create JavaScript object from array of properties and array of matching property values从属性数组和匹配属性值数组创建 JavaScript 对象的有效方法
【发布时间】:2015-07-29 17:19:17
【问题描述】:

是否可以在不使用嵌套 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);
}

【问题讨论】:

    标签: javascript arrays performance time-complexity


    【解决方案1】:

    您可以使用mapforEach

    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;
    });
    

    但它基本上是嵌套循环。

    【讨论】:

    • 查看我的答案,它不使用嵌套的 for 循环!
    【解决方案2】:

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

    例如,使用lodash提供的_.zipObject()

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

    本质上正如@epascarello 所提到的,你仍然在做一个双循环。它只是更优雅(始终取决于编码品味)和更紧凑。

    【讨论】:

      【解决方案3】:

      没有循环...

      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] + '})'));
      

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

      【讨论】:

      • 没有某种循环,它必须看起来像这样。
      • 我只是不想嵌套 for 循环,我发布了答案。感谢您的意见!
      【解决方案4】:

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

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

      【讨论】:

        【解决方案5】:

        我终于想到了一种不使用嵌套循环的有效方法! :)

        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);
        }
        

        【讨论】:

        • 而且它真的很脆弱......最有效的方法是在服务器上启动!
        • 我敢打赌,这比两个循环慢,效率低。 new Function 并不“便宜”。
        猜你喜欢
        • 2022-09-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-11-02
        • 1970-01-01
        • 1970-01-01
        • 2020-06-20
        • 1970-01-01
        相关资源
        最近更新 更多