Reputation:
I have a list of product each list have product code, parent id and product name. when I click product I am pushing into an array of an object listed below.
[
{"pid":"1","pcode":"van","pname":"mobile"},
{"pid":"1","pcode":"van","pname":"hphone"},
{"pid":"2","pcode":"car","pname":"wphone"},
{"pid":"2","pcode":"car","pname":"email"},
{"pid":"4","pcode":"bus","pname":"sms"}
]
how to create the object group based on id and merge the key3
into an array.
{
"pid":"1",
"details":[
{
"pcode":"van",
"pname":["mobile","hphone"]
}
]
},
{
"pid":"2",
"details":[
{
"pcode":"car",
"pname":["wphone","email"]
}
]
},
{
"pid":"3",
"details":[
{
"pcode":"bus",
"pname":["sms"]
}
]
}
Upvotes: 0
Views: 48
Reputation: 8125
Use
.reduce
can be done very easily and one for in loop to collect result. faster result
const data = [
{ pid: "1", pcode: "van", pname: "mobile" },
{ pid: "1", pcode: "something", pname: "hphone" },
{ pid: "1", pcode: "van", pname: "hphone" },
{ pid: "2", pcode: "car", pname: "wphone" },
{ pid: "2", pcode: "car", pname: "email" },
{ pid: "4", pcode: "bus", pname: "sms" }
];
let result = data.reduce((map, cur) => {
if (!map[cur.pid]) {
map[cur.pid] = {
pid: cur.pid,
details: []
}
}
let hasMatch = false
map[cur.pid].details.forEach(x => {
if (x.pcode == cur.pcode) {
hasMatch = true
x.pname.push(cur.pname)
}
})
if (!hasMatch) {
map[cur.pid].details.push({
pcode: cur.pcode,
pname: [cur.pname]
})
}
return map
}, {})
let finalResult = []
for (const r in result) {
finalResult.push(result[r])
}
console.log(JSON.stringify(finalResult, null, 4));
Upvotes: 1
Reputation: 38094
It is possbible to use reduce
method to create grouped array by pid
. Then we can use map
method to assign sequantial pid
:
const obj = arr.reduce((a, {pid, pcode, pname}) => {
a[pid] = a[pid] || {pid, details: []};
if (a[pid].details.length === 0)
a[pid].details.push({pcode, pname:[pname]});
else
a[pid].details[0].pname.push(pname);
return a;
}, {})
const result = Object.values(obj).map((v, index) => ({...v, pid: ++index,}))
console.log(result);
An example:
let arr = [
{"pid":"1","pcode":"van","pname":"mobile"},
{"pid":"1","pcode":"van","pname":"hphone"},
{"pid":"2","pcode":"car","pname":"wphone"},
{"pid":"2","pcode":"car","pname":"email"},
{"pid":"4","pcode":"bus","pname":"sms"}
];
const obj = arr.reduce((a, {pid, pcode, pname}) => {
a[pid] = a[pid] || {pid, details: []};
if (a[pid].details.length === 0)
a[pid].details.push({pcode, pname:[pname]});
else
a[pid].details[0].pname.push(pname);
return a;
}, {})
const result = Object.values(obj).map((v, index) => ({...v, pid: ++index,}))
console.log(result);
Upvotes: 0
Reputation: 15166
I would use .reduce()
for this scenario thus inside you can use .find()
to create the desired output. The last pid
for bus
should be 4
instead of 3
anyway based on the listed array.
Try the following:
const data = [ {"pid":"1","pcode":"van","pname":"mobile"},{"pid":"1","pcode":"van","pname":"hphone"},{"pid":"2","pcode":"car","pname":"wphone"},{"pid":"2","pcode":"car","pname":"email"}, {"pid":"4","pcode":"bus","pname":"sms"}];
const result = data.reduce((a, c) => {
const found = a.find(e => e.pid === c.pid);
if (found) found.details[0].pname.push(c.pname);
else a.push({ pid: c.pid, details: [
{ pcode: c.pcode, pname: [ c.pname ] }
]});
return a;
}, []);
console.log(result);
I hope this helps!
Upvotes: 2