const array = [{
"id": "1",
"main": [{
"type": "a",
"nu": '0',
"role": 1
}],
}, {
"id": "2",
"main": [{
"type": "b",
"nu": '0',
"role": 2
}],
}, {
"id": "3",
"main": [{
"type": "c",
"nu": '0',
"role": 2
}],
}, {
"id": "4",
"main": [{
"type": "d",
"nu": '0',
"role": 2
}],
}]
From above object, i want to combine id- 2,3 and 4 into one key which has 3 objects.
const result = [array.reduce((acc, {id, main}) => {
const { nu, role, type } = main[0]
const hash = `${nu}-${role}`;
acc[hash] = acc[hash] ? [{ ...acc[hash] }, {type: type, id: id }] :
{ type, id: [id] };
return acc;
}, {})];
Expected:
Example:
const array = [{
"id": "1",
"main": [{
"type": "a",
"nu": '0',
"role": 1
}],
}, {
"id": "2",
"main": [{
"type": "b",
"nu": '0',
"role": 2
}],
}, {
"id": "3",
"main": [{
"type": "c",
"nu": '0',
"role": 2
}],
}, {
"id": "4",
"main": [{
"type": "d",
"nu": '0',
"role": 2
}],
}]
const result = [array.reduce((acc, {id, main}) => {
const { nu, role, type } = main[0]
const hash = `${nu}-${role}`;
acc[hash] = acc[hash] ? [{ ...acc[hash] }, {type: type, id: id }] :
{ type, id: [id] };
return acc;
}, {})];
console.log(result);
I am not sure where i am going wrong, can someone please help ?
CodePudding user response:
You could reduce the arrays with an object and a common key with padded zeroes at start.
const
data = [{ id: "1", main: [{ type: "a", nu: "0", role: 1 }] }, { id: "2", main: [{ type: "b", nu: "0", role: 2 }] }, { id: "3", main: [{ type: "c", nu: "0", role: 2 }] }, { id: "4", main: [{ type: "d", nu: "0", role: 2 }] }],
result = data.reduce((r, { id, main }) => {
main.forEach(({ type, nu, role }) => {
const key = `${nu.toString().padStart(3, 0)}-${role}`;
(r[key] ??= []).push({ id, type });
});
return r;
}, {});
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
For getting an exact result, like in picture, you could wrap id
of the first object of a group in an array and if a group has more than one object take an array.
const
data = [{ id: "1", main: [{ type: "a", nu: "0", role: 1 }] }, { id: "2", main: [{ type: "b", nu: "0", role: 2 }] }, { id: "3", main: [{ type: "c", nu: "0", role: 2 }] }, { id: "4", main: [{ type: "d", nu: "0", role: 2 }] }],
result = data.reduce((r, { id, main }) => {
main.forEach(({ type, nu, role }) => {
const key = `${nu.toString().padStart(3, 0)}-${role}`;
r[key] = r[key]
? [].concat(r[key], { id, type })
: { id: [id], type };
});
return r;
}, {});
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
CodePudding user response:
I got your issue, you need to keep a single item just as a JSON (in 0-1
), and when there are more than one items they should be inside an array of JSON (in 0-2
).
This should fix the issue. Just added an additional check for the above-mentioned case.
const array = [ { id: "1", main: [ { type: "a", nu: "0", role: 1, }, ], }, { id: "2", main: [ { type: "b", nu: "0", role: 2, }, ], }, { id: "3", main: [ { type: "c", nu: "0", role: 2, }, ], }, { id: "4", main: [ { type: "d", nu: "0", role: 2, }, ], }, ];
const result = [
array.reduce((acc, { id, main }) => {
const { nu, role, type } = main[0];
const hash = `${nu.padStart(3, 0)}-${role}`;
acc[hash] = acc[hash]
? Array.isArray(acc[hash]) ? [...acc[hash], { type: type, id: id }] : [acc[hash], { type: type, id: id }]
: { type, id: [id] }
return acc;
}, {}),
];
console.log(JSON.stringify(result, null, 2));