2012-02-13 133 views
16

我有两个数组:合并两个数组,以形成一个JavaScript对象

var columns = ["Date", "Number", "Size", "Location", "Age"]; 

var rows = [["2001", "5", "Big", "Sydney", "25"],["2005", "2", "Med", "Melbourne", "50"],["2012", "20", "Huge", "Brisbane", "80"]]; 

我想将它们合并成一个JavaScript对象的行阵列中的每个项目。之后,我想将每个对象都推送到一个新的数组中。

像:

var newarray = []; 

//'thing' should be the same structure for each row item 
var thing = { 
    "Date" : "2001", 
    "Number" : "5", 
    "Size":"Big", 
    "Location":"Sydney", 
    "Age":"25" 
} 

newarray.push(thing); 

我能做到这一点,当我知道列的名字,但我需要能够将数据存储在这种方式,当列名是未知的 - 即,基于列数组的索引。 (根据rows.length)连连

 for(var y = 0; y < rows.length; y++){ 

      for(var i = 0; i < columns.length; i++){ 
       thing[columns[i]] = rows[i][i]; 
      } 
       newarray.push(thing) 
     } 

只存储的第一项上面的代码:

我试图像这样之前。

我不明白如何结合列名与行来创建一个对象数组。 'rows'包含数组的事实尤其令人困惑。

回答

9

在外部循环的每次迭代的开始创建一个新的thing对象。如果你不这样做,每当你说thing[columns[i]]时,你将覆盖同一个对象的属性,当你将它推入newarray时,你会得到一个数组,完整引用同一个对象。此外,内环路是确保你得到正确的指标(目前你已经有了一个[i][i]代替[y][i]):

var newarray = [], 
    thing; 

for(var y = 0; y < rows.length; y++){ 
    thing = {}; 
    for(var i = 0; i < columns.length; i++){ 
     thing[columns[i]] = rows[y][i]; 
    } 
    newarray.push(thing) 
} 

“是‘行’包含数组是特别令人困惑的事实。”

对于示例数据rows.length为3,并且rows[0]是阵列:

["2001", "5", "Big", "Sydney", "25"] 

rows[0][3]是 “悉尼”。

以此为例,您应该能够看到rows[y][i]会为您提供的每个值yi ...

1

您需要指定正确的行。您正在使用该列。将rows[i][i]替换为rows[y][i]。此外,看起来你是反复使用同一个thing对象。相反,您应该通过数组重新定义每次迭代(var thing = {};)。

var newarray = []; 
    for (var y = 0; y < rows.length; y++) { 
     var thing = {}; 
     for (var i = 0; i < columns.length; i++) { 
      thing[columns[i]] = rows[y][i]; 
     } 
     newarray.push(thing); 
    } 
+0

谢谢,我想这样的说法,和我有同样的问题。请参阅:[JSFiddle](http://jsfiddle.net/tamarasaurus/V42Hx/)。我错过了什么吗? – tamarasaurus 2012-02-13 06:21:52

+0

@tamarasaurus,你看到我的最新更新吗?我添加了一个部分,指定您需要在循环的每次迭代中设置'var thing = []'。你的JSFiddle没有显示。 – 2012-02-13 06:30:10

+0

查看http://jsfiddle.net/V42Hx/2/并添加了更改。似乎工作。 – 2012-02-13 06:31:51

0

你只需要重置thing

for(var y = 0; y < rows.length; y++){ 
    for(var i = 0; i < columns.length; i++){ 
     thing[columns[i]] = rows[y][i]; 
    } 

    newarray.push(thing); 
    thing = {};  
} 

看到更新:fiddle

19

你还可做更以数据为中心的方式:

var columns = ["Date", "Number", "Size", "Location", "Age"]; 

var rows = [ 
    ["2001", "5", "Big", "Sydney", "25"], 
    ["2005", "2", "Med", "Melbourne", "50"], 
    ["2012", "20", "Huge", "Brisbane", "80"] 
]; 

var result = rows.map(function(row) { 
    return row.reduce(function(result, field, index) { 
    result[columns[index]] = field; 
    return result; 
    }, {}); 
}); 

这样你就不必处理临时数组。

如果你的代码应该浏览器以及工作,我建议你看一看在underscore.js使用map + reduce

4

如果您正在使用Underscore.js有_.object(list, [values])

而这里的它是如何实现的:

_.object = function(list, values) { 
    if (list == null) return {}; 
    var result = {}; 
    for (var i = 0, length = list.length; i < length; i++) { 
    if (values) { 
     result[list[i]] = values[i]; 
    } else { 
     result[list[i][0]] = list[i][1]; 
    } 
    } 
    return result; 
}; 
+0

+1。很高兴知道如何用纯JavaScript来做到这一点,但为什么要重新发明轮子?这是最好的解决方案恕我直言。知道/使用下划线或lodash很重要。 – Jess 2014-03-10 21:05:01

3

使用的功能会像NNNNNN说,但有小幅调整

var columns = ["Date", "Number", "Size", "Location", "Age"]; 

var rows = [ 
    ["2001", "5", "Big", "Sydney", "25"], 
    ["2005", "2", "Med", "Melbourne", "50"], 
    ["2012", "20", "Huge", "Brisbane", "80"] 
]; 

var result = rows.map(function(row) { 
    return row.reduce(function(result, field, index) { 
    result[columns[index]] = field; 
    return result 
    }, {}); 
}); 
0

除了循环遍历整个表格外,还可以使用columns数组生成Row类(使用defineProperty),然后使用该类行类将行数组包装到行数组中。 Row对象的结果数组然后绑定到原始行数组,这样一个中的更改反映在另一个中。根据你的用例,这可能是有用的或者是一个问题。下面的代码片段给出了一个工作示例。

var columns = ["Date", "Number", "Size", "Location", "Age"]; 
 

 
var rows = [ 
 
    ["2001", "5", "Big", "Sydney", "25"], 
 
    ["2005", "2", "Med", "Melbourne", "50"], 
 
    ["2012", "20", "Huge", "Brisbane", "80"] 
 
]; 
 

 
var table = create_table(columns, rows); 
 

 
// 
 
for (var i = 0; i<table.length; i++) { 
 
    document.writeln("The thing in " + table[i].Location + " is " + table[i].Size + "<br/>"); 
 
} 
 

 
// The rows in table are still tied to those in the rows variable 
 
table[0].Size = "Small"; 
 
document.writeln(JSON.stringify(rows[0])); 
 

 
function create_table(columns, rows) { 
 
    // Create a Row class with the given columns 
 
    for (var i=0; i<columns.length; i++) { 
 
    var c = columns[i]; 
 
    Object.defineProperty(Row.prototype, c, { 
 
     enumerable: true, 
 
     get: getter(i), 
 
     set: setter(i), 
 
    }); 
 
    } 
 
    // Wrap the rows in row objects and return the resulting array 
 
    var r = new Array(rows.length); 
 
    for (var i=0; i<rows.length; i++) { 
 
    r[i] = new Row(rows[i]); 
 
    } 
 
    return r; 
 

 
    function Row(row) { this._ = row; } 
 

 
    // Generators for the getter and setter functions, with variable i stored in a closure. 
 
    function getter(i) { 
 
    return function(){ 
 
     return this._[i]; 
 
    }; 
 
    } 
 
    function setter(i) { 
 
    return function(val){ 
 
     return this._[i] = val; 
 
    }; 
 
    } 
 
}

0

我想我的解决方案是解决你的问题

代码:

var keys = columns, 
     values = rows, 
     finalarray = []; 

     values.forEach((data,index) =>{ 
      var objJSON = new Object(); 
      for (i = 0; i < keys.length; i++) { 
       objJSON[keys[i]] = data[i]; 
       } 
      finalarray.push(objJSON); 
     }); 

答案:

console.log(finalarray) 

[{ 
    "Date" : "2001", 
    "Number" : "5", 
    "Size":"Big", 
    "Location":"Sydney", 
    "Age":"25" 
}, 
... 
}] 
0

您可以使用此功能,下面ES6代码:

const assemblyData = (columns, rows) => { 
    return rows.map((row) => { 
     return row.reduce((res, field, index) => { 
     res[columns[index]] = field; 
     return res 
     }, {}); 
    }); 
} 
相关问题