2016-02-09 38 views
-2

我已經在Stack上搜索了此問題,但似乎無法找到答案。如果使用reduce,for each或filter共享屬性值,則將JSON數組中的對象結合起來

我工作的一個項目,並試圖找出如何減少對象的數量在一個JSON數組,並從共享使用.reduce.forEach,或.filtername屬性的值對象結合value S,以便具有給定名稱的所有值將被配對在一起。我可以用reduce和一個附加的鍵控對象來做到這一點,但我想把它作爲一個簡單的JSON數組。我已經嘗試了各種排列filterreduce,但他們似乎正在返回奇怪的錯誤。

這裏的JavaScript代碼,我的工作:

//Json Data 
var json = [{ 
    "name": "Value0", 
    "value": "Sample0", 
    "truthy": true 
}, { 
    "name": "Value0", 
    "value": "Sample1", 
    "truthy": false 
}, { 
    "name": "Value0", 
    "value": "Sample2", 
    "truthy": true 
}, { 
    "name": "Value0", 
    "value": "Sample3", 
    "truthy": false 
}, { 
    "name": "Value1", 
    "value": "Sample4", 
    "truthy": true 
}, { 
    "name": "Value1", 
    "value": "Sample5", 
    "truthy": false 
}, { 
    "name": "Value1", 
    "value": "Sample6", 
    "truthy": true 
}, { 
    "name": "Value1", 
    "value": "Sample7", 
    "truthy": false 
}, { 
    "name": "Value2", 
    "value": "Sample8", 
    "truthy": true 
}, { 
    "name": "Value2", 
    "value": "Sample9", 
    "truthy": false 
}, { 
    "name": "Value2", 
    "value": "Sample10", 
    "truthy": true 
}, { 
    "name": "Value2", 
    "value": "Sample11", 
    "truthy": false 
}, { 
    "name": "Value3", 
    "value": "Sample12", 
    "truthy": true 
}, { 
    "name": "Value3", 
    "value": "Sample13", 
    "truthy": false 
}, { 
    "name": "Value3", 
    "value": "Sample14", 
    "truthy": true 
}, { 
    "name": "Value3", 
    "value": "Sample15", 
    "truthy": false 
}, { 
    "name": "Value4", 
    "value": "Sample16", 
    "truthy": true 
}, { 
    "name": "Value4", 
    "value": "Sample17", 
    "truthy": false 
}, { 
    "name": "Value4", 
    "value": "Sample18", 
    "truthy": true 
}, { 
    "name": "Value4", 
    "value": "Sample19", 
    "truthy": false 
}, { 
    "name": "Value5", 
    "value": "Sample20", 
    "truthy": true 
}, { 
    "name": "Value5", 
    "value": "Sample21", 
    "truthy": false 
}, { 
    "name": "Value5", 
    "value": "Sample22", 
    "truthy": true 
}, { 
    "name": "Value5", 
    "value": "Sample23", 
    "truthy": false 
}, { 
    "name": "Value6", 
    "value": "Sample24", 
    "truthy": true 
}, { 
    "name": "Value6", 
    "value": "Sample25", 
    "truthy": false 
}, { 
    "name": "Value6", 
    "value": "Sample26", 
    "truthy": true 
}, { 
    "name": "Value6", 
    "value": "Sample27", 
    "truthy": false 
}, { 
    "name": "Value7", 
    "value": "Sample28", 
    "truthy": true 
}, { 
    "name": "Value7", 
    "value": "Sample29", 
    "truthy": false 
}, { 
    "name": "Value7", 
    "value": "Sample30", 
    "truthy": true 
}, { 
    "name": "Value7", 
    "value": "Sample31", 
    "truthy": false 
}, { 
    "name": "Value8", 
    "value": "Sample32", 
    "truthy": true 
}, { 
    "name": "Value8", 
    "value": "Sample33", 
    "truthy": false 
}, { 
    "name": "Value8", 
    "value": "Sample34", 
    "truthy": true 
}, { 
    "name": "Value8", 
    "value": "Sample35", 
    "truthy": false 
}, { 
    "name": "Value9", 
    "value": "Sample36", 
    "truthy": true 
}, { 
    "name": "Value9", 
    "value": "Sample37", 
    "truthy": false 
}, { 
    "name": "Value9", 
    "value": "Sample38", 
    "truthy": true 
}, { 
    "name": "Value9", 
    "value": "Sample39", 
    "truthy": false 
}, { 
    "name": "Value10", 
    "value": "Sample40", 
    "truthy": true 
}, { 
    "name": "Value10", 
    "value": "Sample41", 
    "truthy": false 
}, { 
    "name": "Value10", 
    "value": "Sample42", 
    "truthy": true 
}, { 
    "name": "Value10", 
    "value": "Sample43", 
    "truthy": false 
}, { 
    "name": "Value11", 
    "value": "Sample44", 
    "truthy": true 
}, { 
    "name": "Value11", 
    "value": "Sample45", 
    "truthy": false 
}, { 
    "name": "Value11", 
    "value": "Sample46", 
    "truthy": true 
}, { 
    "name": "Value11", 
    "value": "Sample47", 
    "truthy": false 
}, { 
    "name": "Value12", 
    "value": "Sample48", 
    "truthy": true 
}, { 
    "name": "Value12", 
    "value": "Sample49", 
    "truthy": false 
}, { 
    "name": "Value12", 
    "value": "Sample50", 
    "truthy": true 
}, { 
    "name": "Value12", 
    "value": "Sample51", 
    "truthy": false 
}, { 
    "name": "Value13", 
    "value": "Sample52", 
    "truthy": true 
}, { 
    "name": "Value13", 
    "value": "Sample53", 
    "truthy": false 
}, { 
    "name": "Value13", 
    "value": "Sample54", 
    "truthy": true 
}, { 
    "name": "Value13", 
    "value": "Sample55", 
    "truthy": false 
}, { 
    "name": "Value14", 
    "value": "Sample56", 
    "truthy": true 
}, { 
    "name": "Value14", 
    "value": "Sample57", 
    "truthy": false 
}, { 
    "name": "Value14", 
    "value": "Sample58", 
    "truthy": true 
}, { 
    "name": "Value14", 
    "value": "Sample59", 
    "truthy": false 
}, { 
    "name": "Value15", 
    "value": "Sample60", 
    "truthy": true 
}, { 
    "name": "Value15", 
    "value": "Sample61", 
    "truthy": false 
}, { 
    "name": "Value15", 
    "value": "Sample62", 
    "truthy": true 
}, { 
    "name": "Value15", 
    "value": "Sample63", 
    "truthy": false 
}, { 
    "name": "Value16", 
    "value": "Sample64", 
    "truthy": true 
}, { 
    "name": "Value16", 
    "value": "Sample65", 
    "truthy": false 
}, { 
    "name": "Value16", 
    "value": "Sample66", 
    "truthy": true 
}, { 
    "name": "Value16", 
    "value": "Sample67", 
    "truthy": false 
}, { 
    "name": "Value17", 
    "value": "Sample68", 
    "truthy": true 
}, { 
    "name": "Value17", 
    "value": "Sample69", 
    "truthy": false 
}, { 
    "name": "Value17", 
    "value": "Sample70", 
    "truthy": true 
}, { 
    "name": "Value17", 
    "value": "Sample71", 
    "truthy": false 
}, { 
    "name": "Value18", 
    "value": "Sample72", 
    "truthy": true 
}, { 
    "name": "Value18", 
    "value": "Sample73", 
    "truthy": false 
}, { 
    "name": "Value18", 
    "value": "Sample74", 
    "truthy": true 
}, { 
    "name": "Value18", 
    "value": "Sample75", 
    "truthy": false 
}, { 
    "name": "Value19", 
    "value": "Sample76", 
    "truthy": true 
}, { 
    "name": "Value19", 
    "value": "Sample77", 
    "truthy": false 
}, { 
    "name": "Value19", 
    "value": "Sample78", 
    "truthy": true 
}, { 
    "name": "Value19", 
    "value": "Sample79", 
    "truthy": false 
}, { 
    "name": "Value20", 
    "value": "Sample80", 
    "truthy": true 
}, { 
    "name": "Value20", 
    "value": "Sample81", 
    "truthy": false 
}, { 
    "name": "Value20", 
    "value": "Sample82", 
    "truthy": true 
}, { 
    "name": "Value20", 
    "value": "Sample83", 
    "truthy": false 
}, { 
    "name": "Value21", 
    "value": "Sample84", 
    "truthy": true 
}, { 
    "name": "Value21", 
    "value": "Sample85", 
    "truthy": false 
}, { 
    "name": "Value21", 
    "value": "Sample86", 
    "truthy": true 
}, { 
    "name": "Value21", 
    "value": "Sample87", 
    "truthy": false 
}, { 
    "name": "Value22", 
    "value": "Sample88", 
    "truthy": true 
}, { 
    "name": "Value22", 
    "value": "Sample89", 
    "truthy": false 
}, { 
    "name": "Value22", 
    "value": "Sample90", 
    "truthy": true 
}, { 
    "name": "Value22", 
    "value": "Sample91", 
    "truthy": false 
}, { 
    "name": "Value23", 
    "value": "Sample92", 
    "truthy": true 
}, { 
    "name": "Value23", 
    "value": "Sample93", 
    "truthy": false 
}, { 
    "name": "Value23", 
    "value": "Sample94", 
    "truthy": true 
}, { 
    "name": "Value23", 
    "value": "Sample95", 
    "truthy": false 
}, { 
    "name": "Value24", 
    "value": "Sample96", 
    "truthy": true 
}, { 
    "name": "Value24", 
    "value": "Sample97", 
    "truthy": false 
}, { 
    "name": "Value24", 
    "value": "Sample98", 
    "truthy": true 
}, { 
    "name": "Value24", 
    "value": "Sample99", 
    "truthy": false 
}]; 
//removing irrelevant data items 
json = json.map(function(item) { 
    return { 
     "name": item.name, 
     "values": [item.value] 
    }; 
}); 
//attempt at reduce function 

json.reduce(function(p, c) { 
    if (p && p.name === c.name) { 
     p.value.push(c.value); 
    } 
}); 
/* 
//attempt at filter function 
json = json.filter(function(item,i) { 
if (i > 0 && item.name === json[i-1].name) { 
json[i-1].value.push(item.name); 
} 
}); 

//forEach attempt /* 
json = json.forEach(function(item, i, arr) { 
    if (i > 0) { 
    if (arr[i].name === arr[i - 1].name) { 
     var pop = json.pop(); 
     json[i - 1].value.push(pop.value); 
    } 
    } 
}); 
*/ 


console.log(JSON.stringify(json)); 

理想情況下,我想有這樣的:

var json = [{ 
    "name": "Value0", 
    "values": ["Sample0", "Sample1", "Sample2", "Sample3"] 
}, { 
    "name": "Value1", 
    "values": ["Sample4", "Sample5", "Sample6", "Sample7"] 
} 

+0

什麼是應該發生的'truthy'財產?你的輸出在第二個對象中,但它爲什麼是'真'? – nnnnnn

+0

它應該消失。 – litel

+0

如果它應該消失,您應該修改您的「理想」部分,因爲您顯示它仍然存在於其中一個對象中。另外,你是否可以假設所有具有相同名稱的對象將被組合在一起?即所有的「Value0」對象會先出現,然後是所有的「Value1」對象,然後是所有的「Value2」對象?或者他們可以混合起來? – Elezar

回答

1

不是最完美的解決方案,但應完全按照您要求

var newData = json.reduce(function (arr, currentValue){ 
    var index = false; 
    arr.forEach(function(item, i) { 
     if (item.name === currentValue.name && (item.truthy && currentValue.truthy || item.truthy === undefined && currentValue.truthy === false))  { 
      index = i; 
     } 
    }); 

    if (index === false) { 
     var newItem = { 
      name: currentValue.name, 
      values: [currentValue.value] 
     }; 
     if (currentValue.truthy) { 
      newItem.truthy = true; 
     } 
     arr.push(newItem); 

     return arr; 
    } 

    arr[index].values.push(currentValue.value); 

    return arr; 
}, []); 

也,小提琴:https://jsfiddle.net/6xph0g9b/

+0

比我想象的更復雜一些,但它只需進行一些修改即可完美工作。謝謝! – litel

0

這是最容易想到這分兩個階段:1)如何過濾我需要的數據?然後2)如何將其縮小爲我想要的格式?

爲了完成#1,使用filter功能,它看起來像:

json.filter((el) => el.truthy) 

這將返回一個新的數組與所有有true一個truthy值的元素。然後,將它們向下咚成名稱/值對,則通過reduce運行它們:

json.filter((el) => el.truthy).reduce((seen, el) => { 
    if(!seen[el.name]) seen[el.name] = []; // If our initial state doesn't have a key for this element's name, then initialize it to an empty array. 
    if(seen[el.name].indexOf(el.value) === -1) // If our state doesn't already contain this element's value, then add it. 
    seen[el.name].push(el.value); 
    return seen; // Return state 
}, {} /* Initial state is an empty object */) 

這產生了具有el.name的鍵的對象:與陣列的一個值(例如Value0) Value0的所有value字段(例如:Sample0Sample2)。

這會讓你走上正軌嗎?

+0

在JS小提琴中,它似乎不適合我。唉,我不能使用ECMAScript6。 https://jsfiddle.net/xax6xLuj/ 另外,希望它不是太大的一個問題,你能分解'!看到[el.name]'嗎?我在'reduce'中多次使用'!p [c]'的版本,但我從來沒有真正理解它的作用。 – litel

+0

@litel該JSFiddle中的代碼不是我提供的代碼。在JSFiddle中,由於「json = json.forEach(...)'''將'json'分配給'undefined'。'forEach'在一個數組上運行一個函數,並且什麼都不返回(undefined),所以你將json分配給undefined,然後試圖從undefined運行reduce。 –

+0

此外,我不想創建一個鍵控對象,並將其轉換回數組(這並不難)。我試圖找出是否有方法來組合JSON數組中的項目而不將其更改爲對象。我試圖減少步驟的數量。 – litel

相關問題