2015-06-18 92 views
1

我有一個按ID分組的集合。每個id都包含對象數組。我想遍歷它並創建一個目標集合,它將按照示例中所示的「Id」列進行分組。我不會使用下劃線js。我必須使用javascript reduce方法來實現這一點。Groupby不使用下劃線js

var targetCollection = [{ 
 
    123456: [ 
 
     { "Id": "1", "name": "xxx", "age": "22" }, 
 
     { "Id": "1", "name": "yyy", "age": "15" }, 
 
     { "Id": "5", "name": "zzz", "age": "59" } 
 
    ], 
 
    789456: [ 
 
     { "Id": "1", "name": "xxx", "age": "22" }, 
 
     { "Id": "1", "name": "yyy", "age": "15" }, 
 
     { "Id": "5", "name": "zzz", "age": "59" } 
 
    ] 
 
}] 
 

 
var targetOutput = [{ 
 
    123456: { 
 
     1: [{ "Id": "1", "name": "xxx", "age": "22" }, { "Id": "1", "name": "yyy", "age": "15" }], 
 
     5: [{ "Id": "5", "name": "zzz", "age": "59" }] 
 
    }, 
 
    789456: { 
 
     1: [{ "Id": "1", "name": "xxx", "age": "22" }, { "Id": "1", "name": "yyy", "age": "15" }], 
 
     5: [{ "Id": "5", "name": "zzz", "age": "59" }] 
 
    } 
 
}]

Code Snippet I have tried which didn't work 
 

 
var newArray = []; 
 
$.each(targetCollection, function (key, value) { 
 
    var newTarget = $(this); 
 
    var targetCollectionNew = newTarget.reduce(function (result, current) { 
 
     result[current.ParentAreaID] = result[current.ParentAreaID] || []; 
 
     result[current.ParentAreaID].push(current); 
 
     return result; 
 
    }, {}); 
 

 
    newArray.push(targetCollectionNew); 
 
}); 
 

 
console.log('newArray', newArray);

我試圖與陣列減少方法,它沒有工作。請幫幫我。

+0

的解決方案是很容易的,但你嘗試過這麼遠嗎?哪些代碼不起作用? –

+0

如果你能讓我知道解決方案,那將是非常棒的。我已經嘗試了很多東西,現在它不會退縮到你所要求的位置。 –

+0

發佈最新代碼不應太難。否則,你只需發佈一個問題集。 –

回答

3

你原來的嘗試的問題是你需要有兩個循環,因爲在第一個newValue是一個對象不是數組,所以沒有reduce方法就可以了。

更簡單的解決方案是使用地圖(您可以使用forEach$.each)並減少第二個循環(我使用簡單的for-in)。

事情是這樣的:

var targetCollection = [{ 
 
    123456: [ 
 
     { "Id": "1", "name": "xxx", "age": "22" }, 
 
     { "Id": "1", "name": "yyy", "age": "15" }, 
 
     { "Id": "5", "name": "zzz", "age": "59" } 
 
    ], 
 
    789456: [ 
 
     { "Id": "1", "name": "xxx", "age": "22" }, 
 
     { "Id": "1", "name": "yyy", "age": "15" }, 
 
     { "Id": "5", "name": "zzz", "age": "59" } 
 
    ] 
 
}]; 
 

 
var result = targetCollection.map(function(obj) { 
 
    for (var key in obj) { 
 
     obj[key] = obj[key].reduce(function(prev, curr) { 
 
      if (!prev[curr.Id]) prev[curr.Id] = []; 
 
      prev[curr.Id].push(curr); 
 
      return prev; 
 
     }, {}); 
 
    } 
 
    return obj; 
 
}); 
 

 
document.write('<pre>' + JSON.stringify(result, null, 4) + '</pre>');

+0

嘿!你知道你是冠軍!!!這工作完美,並感謝解釋這個錯誤。這真的有幫助。 –

+1

這將修改原始對象。看到我的答案爲什麼。 –

+0

@JasonCust是的我知道,但我覺得這不是問題(也許這是需要重新構建的服務器的響應)。在大多數情況下,我希望對象在包裝器數組轉換後仍然是引用。順便說一句,你的解決方案也是通過引用傳遞對象。 – dfsq

2

你應該比較當前的對象,targetCollection,和您所需的輸出對象,targetOutput,謀劃變革,你將需要:

targetCollection: Array --> Object --> Array --> Object 
targetObject: Array --> Object --> Object --> Array --> Object 

您可以看到外部數組將是1:1映射,所以t這裏沒有必要在這裏減少。

下一級是對象,但它又是1:1映射。但是,因爲JavaScript通過引用傳遞對象,您將需要創建一個新對象以避免修改原始對象。既然我們是從另一個對象創建一個對象,我們可以利用Object.keys的強大功能來創建一個數組,然後使用Array.reduce從這些關鍵字創建一個對象。

第三個層次是我們第一次遇到結構從數組到實體的真實轉換的地方。再次,我們可以使用Array.reduce來幫助這一步。

所以從這個攻擊計劃你可以看到流程應該是map --> reduce --> reduce

var targetCollection = [{ 
 
    123456: [{ 
 
    "Id": "1", 
 
    "name": "xxx", 
 
    "age": "22" 
 
    }, { 
 
    "Id": "1", 
 
    "name": "yyy", 
 
    "age": "15" 
 
    }, { 
 
    "Id": "5", 
 
    "name": "zzz", 
 
    "age": "59" 
 
    }], 
 
    789456: [{ 
 
    "Id": "1", 
 
    "name": "xxx", 
 
    "age": "22" 
 
    }, { 
 
    "Id": "1", 
 
    "name": "yyy", 
 
    "age": "15" 
 
    }, { 
 
    "Id": "5", 
 
    "name": "zzz", 
 
    "age": "59" 
 
    }] 
 
}]; 
 

 
// 1:1 mapping 
 
var targetOutput = targetCollection.map(function(obj) { 
 
    // 1:1 mapping but we need to create a new object to 
 
    // avoid modifying the original object 
 
    // Object.keys returns an array of keys (that are enumerable) 
 
    // and then reduce creates the new object 
 
    return Object.keys(obj).reduce(function(newObj, key) { 
 
    // The desired transformation takes place here 
 
    newObj[key] = obj[key].reduce(function(idObj, el) { 
 
     idObj[el.Id] = idObj[el.Id] || []; 
 
     // This will pass by reference the internal objects 
 
     // so you could use the prior technique to create 
 
     // a new object to avoid downstream modification 
 
     idObj[el.Id].push(el); 
 

 
     return idObj; 
 
    }, {}); 
 

 
    return newObj; 
 
    }, {}); 
 
}); 
 

 
document.write('<h3>targetCollection</h3><pre>' + JSON.stringify(targetCollection, null, 4) + '</pre>'); 
 
document.write('<h3>targetOutput</h3><pre>' + JSON.stringify(targetOutput, null, 4) + '</pre>');