问题
Please take a look at my current json. I want to recursively group by this one.
[{ "mode": "AR", "fname": "ta", "lname": "da", "w_lng":
"1.23", "w_lat": "2.23","other":"a"},
{ "mode": "AR", "fname": "ta", "lname": "Dash", "w_lng":
"1.23", "w_lat": "2.23","other":"b" },
{ "mode": "AR1", "fname": "ka", "lname": "ja", "w_lng":
"3.23", "w_lat": "4.23","other":"c" },
{ "mode": "AR", "fname": "Kiran", "lname": "Dash", "w_lng":
"5.23", "w_lat": "6.23","other":"d" },
{ "mode": "AR", "fname": "Milan", "lname": "Dash", "w_lng":
"7.23", "w_lat": "8.23","other":"e" },
{ "mode": "AR1", "fname": "ka", "lname": "ja", "w_lng":
"8.23", "w_lat": "9.23","other":"f" }]
What I am am looking for:
{
"mode": "AR",
"results": [
{
"fname": "ta",
"lname": "da",
"w_level": [
{ "w_lng": "1.23",
"w_lat": "2.23"
"other":[{"other":"a","other":"b"}]
},
{"w_lng": "3.xx",
"w_lat": "4.xx"
"....":[........]
}
]
}
{
"fname": "ka",
"lame": "ja",
"w_level": [
{
"w_lng": "6.xx",
"w_lat": "5.xx"
.....................
}
]
}
]
},
{
"mode": "AR1",
"results": [
{
"fname": "ka",
"lname": "ja",
"w_level": [
{ "w_lng": "6.xx",
"w_lat": "5.xx"
"....":[........]
}
]
}
]
}
What I have tried:
Object.values(inArr.reduce((item, currItem) => {
var { mode, fname, lname } = currItem;
if (!item[mode]) item[mode] = { mode, results: [] };
let w_level = {};
for (let key of Object.keys(currItem)) {
if (key !== "fname" && key !== 'lname' && key !== 'mode') {
w_level[key] = currItem[key];
}
}
item[mode].results.push({fname: fname, lname: lname, w_level: [w_level]});
return item;
}, {}))
But the problem is fname and lname again even it is same. I want to group by recursively. First it will group by mode. Then it will group by fname+lname under this mode. if anything same it will be added like tree.
回答1:
Here is my final solution. The user can specify the key for grouping.
const reduceArrayByKeys = (inArr, keys, restKey) => {
const reduced = inArr.reduce((prev, cur) => {
const copied = { ...cur }
keys.forEach(key => delete copied[key])
const existing = prev.find(item => keys.every(key => item[key] === cur[key]))
if (existing) {
existing[restKey].push(copied)
} else {
const newItem = {}
keys.forEach(key => newItem[key] = cur[key])
newItem[restKey] = [copied]
prev.push(newItem)
}
return prev
}, [])
return reduced
}
We can specify the keys by which we are going to group the array. We can use this reduceArrayByKeys function to group the array as we want. Below is the example code
const reduced = reduceArrayByKeys(inArr, ['mode'], 'results')
reduced.forEach(item => {
const results = item.results
item.results = reduceArrayByKeys(results, ['fname', 'lname'], 'w_level')
item.results.forEach(child => {
child.w_level = reduceArrayByKeys(child.w_level, ['w_lng', 'w_lat'], 'other')
})
})
You can call reduceArrayByKeys function for w_level as well.
来源:https://stackoverflow.com/questions/59779931/how-to-group-by-json-using-reduce