簡體   English   中英

Map Reduce跨性能差的對象的javascript數組

[英]Map Reduce across javascript array of objects with poor performance

我正在嘗試對某些javascript對象進行一些映射/減少操作,並且失敗了。

來自后端的數據看起來像這樣:

[
  {table:"a1", data: {colA:1,colB:2,colC:3}},
  {table:"a2", data: {colA:2,colB:3,colC:4}},
  {table:"a3", data: {colA:3,colB:4,colC:5}}
]

圖表需要以下格式的數據(將源數據鍵作為結果的唯一“名稱”鍵)

[
  {name: 'colA', a1: 1, a2: 2, a3: 3},
  {name: 'colB', a1: 2, a2: 3, a3: 4},
  {name: 'colC', a1: 3, a2: 4, a3: 5}
]

我當前的解決方案當前為O(n^n)因為我正在構建一個結果對象,並每次對其進行循環。 我正在使用ECMA6 / Babel以及Lodash。 任何指導將不勝感激! 謝謝!

編輯:這是我當前的解決方案

var dest = []
Lodash.forEach(source,(o) => {
  var table = o.table;
  Lodash.forEach(o.data, (p,q) => {
    // See if the element is in the array
    const index = Lodash.findIndex(dest,(a) => {return a.name === q});
    if ( index === -1) {
      var obj = {};
      obj[table] = Number(p);
      obj.name = q;
      dest.push(obj);
    } else {
      dest[index][table] = Number(p);
    }
  })
});

首先,您的算法速度實際上是O(n ^ n ^ n),因為您嵌套了3個循環。 我要簡化的方法是先使用一個對象,然后從該對象創建一個數組。 像這樣:

 function convert(original) { var tmp = {}; for(var tableIndex in original) { var tableObj = original[tableIndex]; for(var colKey in tableObj.data) { var col = tableObj.data[colKey]; if(tmp[colKey] === undefined) { tmp[colKey] = {name: colKey}; } tmp[colKey][tableObj.table] = col } } var output = []; for(var index in tmp) { output.push(tmp[index]); } return output; } var original = [ {table:"a1", data: {colA:1,colB:2,colC:3}}, {table:"a2", data: {colA:2,colB:3,colC:4}}, {table:"a3", data: {colA:3,colB:4,colC:5}} ] console.log(convert(original)); 

這樣就無需遍歷結果數組以添加到對象中。 在輸入數組及其數據上進行迭代時,您仍然具有O(n ^ m)+ O(l)條件,但是在每次迭代時也對結果數組進行迭代,就沒有更復雜的速度條件。

此功能還可以處理每個表的數據可能不同的實例。 因此,例如,您可能在其中一項中有colA和colB但沒有colC。 或者您可能在另一個條目上輸入了colD。

如果使用地圖跟蹤最終的列,則可以大大簡化此過程。 通過隨時將它們存儲在地圖中,您可以獲得不斷查找時間的好處。

如果我們說表的數量是N ,列的數量是M那么您將得到O(N * M)。

 let input = [ { table: "a1", data: { colA: 1, colB: 2, colC: 3 } }, { table: "a2", data: { colA: 2, colB: 3, colC: 4 } }, { table: "a3", data: { colA: 3, colB: 4, colC: 5 } } ]; let desiredOutput = [ { name: 'colA', a1: 1, a2: 2, a3: 3 }, { name: 'colB', a1: 2, a2: 3, a3: 4 }, { name: 'colC', a1: 3, a2: 4, a3: 5 } ]; let keys = null; let map = null; input.forEach(row => { if (map === null) { // Cache the column names keys = Object.keys(row.data); // Generates objects such a `{ name: 'colA' }` // and stores them at a key of 'colA' map = keys .reduce((o, k) => (o[k] = { name: k }, o), {}); } // For each column ('colA', 'colB', etc.) keys.forEach(key => { // Create a new property for the table name // ('a1', 'a2', etc.) // and copy the matching column value from the input map[key][row.table] = row.data[key]; }); }); // Convert the map to an array of just the values let output = Object.values(map); console.log(JSON.stringify(output) === JSON.stringify(desiredOutput)); console.log(output); 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM