'Group Object based on ending Number
Here is the sample object
{
abc_0: 'a',
bcd_0: 'b',
cde_0: 'c',
abc_1: 'a',
bcd_1: 'b',
cde_1: 'c',
def_1: 'd',
}
I want to group via the number they end with and wante the expected output to be
{
0: {abc: 'a', bcd: 'b', cde: 'c'},
1: {abc: 'a', bcd: 'b', cde: 'c', def : 'd'},
}
Solution 1:[1]
You may try this solution:
const data = {
abc_0: 'a',
bcd_0: 'b',
cde_0: 'c',
abc_1: 'a',
bcd_1: 'b',
cde_1: 'c',
def_1: 'd',
};
const result = Object.entries(data).reduce((acc, [combo, value]) => {
const [key, index] = combo.split('_');
acc[index] = { ...acc[index], [key]: value };
return acc;
}, {});
console.log(result);
Solution 2:[2]
You can write something like this to achieve it
const obj = {
abc_0: 'a',
bcd_0: 'b',
cde_0: 'c',
abc_1: 'a',
bcd_1: 'b',
cde_1: 'c',
def_1: 'd',
};
const groupByChar = () => {
const res = {};
for (let k in obj){
const char = k.charAt(k.length-1);
if (!res[char]){
res[char] = {};
}
const key = k.substring(0, k.length - 2);
res[char][key] = obj[k];
}
return res;
}
const res = groupByChar();
console.log(res);
Solution 3:[3]
I deliberately disrupted the data sequence to better meet your needs.
const data = {
abc_0: 'a',
abc_1: 'a',
bcd_0: 'b',
bcd_1: 'b',
cde_0: 'c',
cde_1: 'c',
def_0: 'd',
def_1: 'd',
};
const res = Object.keys(data)
.map((key) => {
const [char, num] = key.split('_');
return {
[num]: {
[char]: data[key],
},
};
})
.reduce((acc, cur) => {
const acc_keys = Object.keys(acc);
const [cur_key] = Object.keys(cur);
if (acc_keys.includes(cur_key)) {
acc[cur_key] = { ...acc[cur_key], ...cur[cur_key] };
return {
...acc,
};
} else {
return { ...acc, ...cur };
}
}, {});
console.log(res);
Solution 4:[4]
Another way of writing it
const obj= {
abc_0: 'a',
bcd_0: 'b',
cde_0: 'c',
abc_1: 'a',
bcd_1: 'b',
cde_1: 'c',
def_1: 'd',
}
const filtered = Object.keys(obj).map((el)=>el.split('_')[1]).filter((el, i)=>Object.keys(obj).map((el)=>el.split('_')[1]).indexOf(el)===i);
const res = Object.entries(obj).reduce((acc, curr, i)=>{
const left=curr[0].split('_')[0]
const right=curr[0].split('_')[1]
filtered.forEach((index)=>{
if(right==index){
!acc[index]? acc[index]={}:null
!acc[index][left]?acc[index][left]=obj[`${left}_${right}`]:null
}
})
return acc
},{})
console.log(res);
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | |
Solution 3 | Martin Adams |
Solution 4 | MWO |