2012-02-13 129 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 
     }, {}); 
    }); 
} 
相關問題