I am trying to loop through a array ob objects and group the items of the array into new arrays that have matching id:
API example:
api_array [
{id: 1, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 1, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 1, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 2, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 2, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 2, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 3, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 3, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 3, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 4, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 4, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 4, postcode: 'xxx', street: 'xxx', city: 'xxx'},
];
I am trying to achieve this result:
result [
group_one [
{id: 1, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 1, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 1, postcode: 'xxx', street: 'xxx', city: 'xxx'},
]
group_two [
{id: 2, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 2, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 2, postcode: 'xxx', street: 'xxx', city: 'xxx'},
]
group_three [
{id: 3, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 3, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 3, postcode: 'xxx', street: 'xxx', city: 'xxx'},
]
group_four [
{id: 4, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 4, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 4, postcode: 'xxx', street: 'xxx', city: 'xxx'},
]
]
I have actually managed to achieve it but i think its crazy and am sure there is a better implementation here is what i have done:
const createAddresses = (address) => {
let group_one= [],
group_two = [],
group_three = [],
group_four = [],
group = [];
debugger;
for(let i=0; i < address.length; i++) {
switch (address[i].id) {
case 1:
group_one.push(address[i]);
break;
case 2:
group_two.push(address[i]);
break;
case 3:
group_three.push(address[i]);
break;
case 4:
group_four.push(address[i]);
break;
default:
return address;
}
}
console.log('GROUP', group);
return group.push(group_one, group_two, group_three, group_four);
}
I really dont like this implementation and have tried this:
const obj = address.reduce((acc, cur) => ({...acc, [cur.id]: cur}), {});
and what the above does is the same as my insane for loop function but it only adds last element for each group like so:
result [
0 [
{id: 1, postcode: 'xxx', street: 'xxx', city: 'xxx'},
]
1 [
{id: 2, postcode: 'xxx', street: 'xxx', city: 'xxx'},
]
2 [
{id: 3, postcode: 'xxx', street: 'xxx', city: 'xxx'},
]
3 [`enter code here`
{id: 4, postcode: 'xxx', street: 'xxx', city: 'xxx'},
]
]
but like i have mentioned i need all the elements in side each group any advice please.
I am trying to loop through a array ob objects and group the items of the array into new arrays that have matching id:
API example:
api_array [
{id: 1, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 1, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 1, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 2, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 2, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 2, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 3, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 3, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 3, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 4, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 4, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 4, postcode: 'xxx', street: 'xxx', city: 'xxx'},
];
I am trying to achieve this result:
result [
group_one [
{id: 1, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 1, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 1, postcode: 'xxx', street: 'xxx', city: 'xxx'},
]
group_two [
{id: 2, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 2, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 2, postcode: 'xxx', street: 'xxx', city: 'xxx'},
]
group_three [
{id: 3, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 3, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 3, postcode: 'xxx', street: 'xxx', city: 'xxx'},
]
group_four [
{id: 4, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 4, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 4, postcode: 'xxx', street: 'xxx', city: 'xxx'},
]
]
I have actually managed to achieve it but i think its crazy and am sure there is a better implementation here is what i have done:
const createAddresses = (address) => {
let group_one= [],
group_two = [],
group_three = [],
group_four = [],
group = [];
debugger;
for(let i=0; i < address.length; i++) {
switch (address[i].id) {
case 1:
group_one.push(address[i]);
break;
case 2:
group_two.push(address[i]);
break;
case 3:
group_three.push(address[i]);
break;
case 4:
group_four.push(address[i]);
break;
default:
return address;
}
}
console.log('GROUP', group);
return group.push(group_one, group_two, group_three, group_four);
}
I really dont like this implementation and have tried this:
const obj = address.reduce((acc, cur) => ({...acc, [cur.id]: cur}), {});
and what the above does is the same as my insane for loop function but it only adds last element for each group like so:
result [
0 [
{id: 1, postcode: 'xxx', street: 'xxx', city: 'xxx'},
]
1 [
{id: 2, postcode: 'xxx', street: 'xxx', city: 'xxx'},
]
2 [
{id: 3, postcode: 'xxx', street: 'xxx', city: 'xxx'},
]
3 [`enter code here`
{id: 4, postcode: 'xxx', street: 'xxx', city: 'xxx'},
]
]
but like i have mentioned i need all the elements in side each group any advice please.
Share Improve this question edited Oct 17, 2019 at 14:51 georg 215k56 gold badges322 silver badges398 bronze badges asked Oct 17, 2019 at 13:33 JohnJohn 1,6654 gold badges24 silver badges48 bronze badges 2- I suggest not reinventing the wheel: groupBy, though surely, you can write it yourself, if you want to. You can also look at lodash's source if you need inspiration, although they acmodate for more plex scenarios, and use their other own utility functions. – ASDFGerte Commented Oct 17, 2019 at 13:37
- So, wait, do you want an array of arrays, or an object with keys like "group_1" mapped to an array? – Thomas Preston Commented Oct 17, 2019 at 14:48
9 Answers
Reset to default 5group array of objects by id
//Create a javascript array of objects containing key value pairs id, post
var api_array = [
{id: 1, postcode: '10'},
{id: 1, postcode: '11'},
{id: 2, postcode: '20'},
{id: 2, postcode: '21'},
{id: 2, postcode: '22'},
{id: 3, postcode: '30'}
];
//result is a javascript array containing the groups grouped by id.
let result = [];
//javascript array has a method foreach that enumerates keyvalue pairs.
api_array.forEach(
r => {
//if an array index by the value of id is not found, instantiate it.
if( !result[r.id] ){
//result gets a new index of the value at id.
result[r.id] = [];
}
//push that whole object from api_array into that list
result[r.id].push(r);
}
);
console.log(result[1]);
console.log(result[2]);
console.log(result[3]);
Prints:
[ { id: 1, postcode: '10' }, { id: 1, postcode: '11' } ]
[ { id: 2, postcode: '20' },
{ id: 2, postcode: '21' },
{ id: 2, postcode: '22' } ]
[ { id: 3, postcode: '30' } ]
var objs = [
{ id: 1, postcode: "xxx", street: "xxx", city: "xxx" },
{ id: 1, postcode: "xxx", street: "xxx", city: "xxx" },
{ id: 2, postcode: "xxx", street: "xxx", city: "xxx" },
{ id: 3, postcode: "xxx", street: "xxx", city: "xxx" }
];
var result = objs.reduce(function(r, a) {
r[a.id] = r[a.id] || [];
r[a.id].push(a);
return r;
}, Object.create(null));
console.log(result);
Try to acheive like this:
var api_array = [
{id: 1, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 1, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 1, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 2, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 2, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 2, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 3, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 3, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 3, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 4, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 4, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 4, postcode: 'xxx', street: 'xxx', city: 'xxx'},
];
const result = api_array.reduce((acc, item) => {
acc[`group_${item.id}`] = (acc[`group_${item.id}`] || []);
acc[`group_${item.id}`].push(item);
return acc;
}, {});
console.log(result);
Note: The result will have keys group_1
, group_2
... instead group_one
, group_two
...
If you strictly need that, then make an array for key and values to convert 1 as one.
https://jsfiddle/u4k16ojz/5/
var result = new Array(4);
api_array.forEach(function(item, index){
if (!result[item.id]){
result[item.id] = [];
}
result[item.id].push(item);
})
You could take a Map
for grouping same id
and get the values from the map as result set.
The result set has the same order of the wanted keys.
function groupBy(array, key) {
return Array.from(array
.reduce((m, o) => m.set(o[key], [...(m.get(o[key]) || []), o]), new Map)
.values()
);
}
var data = [{ id: 1, postcode: 'xxx', street: 'xxx', city: 'xxx' }, { id: 1, postcode: 'xxx', street: 'xxx', city: 'xxx' }, { id: 1, postcode: 'xxx', street: 'xxx', city: 'xxx' }, { id: 2, postcode: 'xxx', street: 'xxx', city: 'xxx' }, { id: 2, postcode: 'xxx', street: 'xxx', city: 'xxx' }, { id: 2, postcode: 'xxx', street: 'xxx', city: 'xxx' }, { id: 3, postcode: 'xxx', street: 'xxx', city: 'xxx' }, { id: 3, postcode: 'xxx', street: 'xxx', city: 'xxx' }, { id: 3, postcode: 'xxx', street: 'xxx', city: 'xxx' }, { id: 4, postcode: 'xxx', street: 'xxx', city: 'xxx' }, { id: 4, postcode: 'xxx', street: 'xxx', city: 'xxx' }, { id: 4, postcode: 'xxx', street: 'xxx', city: 'xxx' }],
grouped = groupBy(data, 'id');
console.log(grouped);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Similar to your reduce
example, this iterates over the data and creates a object using the object ids as keys and grouping them together. It then grabs the values from that object.
const api_array = [{id: 1, postcode: 'xxx', street: 'xxx', city: 'xxx'},{id: 1, postcode: 'xxx', street: 'xxx', city: 'xxx'},{id: 1, postcode: 'xxx', street: 'xxx', city: 'xxx'},{id: 2, postcode: 'xxx', street: 'xxx', city: 'xxx'},{id: 2, postcode: 'xxx', street: 'xxx', city: 'xxx'},{id: 2, postcode: 'xxx', street: 'xxx', city: 'xxx'},{id: 3, postcode: 'xxx', street: 'xxx', city: 'xxx'},{id: 3, postcode: 'xxx', street: 'xxx', city: 'xxx'},{id: 3, postcode: 'xxx', street: 'xxx', city: 'xxx'},{id: 4, postcode: 'xxx', street: 'xxx', city: 'xxx'},{id: 4, postcode: 'xxx', street: 'xxx', city: 'xxx'},{id: 4, postcode: 'xxx', street: 'xxx', city: 'xxx'}];
const out = Object.values(api_array.reduce((acc, c) => {
const { id } = c;
// If the object doesn't have a key that matches the id
// create an array as its value and then concat the current object
// to it, otherwise, if the key exists just concat the current object
// to the existing array
acc[id] = (acc[id] || []).concat(c);
return acc;
}, {}));
console.log(out)
You could use the ids as properties of an object
let api_array = [
{id: 1, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 1, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 1, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 2, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 2, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 2, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 3, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 3, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 3, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 4, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 4, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 4, postcode: 'xxx', street: 'xxx', city: 'xxx'},
];
let grouped = groupArray(api_array);
console.log(grouped);
console.log(grouped[1]);
function groupArray(myArray) {
let grouped = {};
for (let i = 0; i < myArray.length; i++) {
let row = myArray[i];
let group = grouped[row.id];
if (!group) {
group = [];
grouped[row.id] = group;
}
group.push(row);
}
return grouped;
}
you can use reduce to grouping like this.
const api_array = [
{id: 1, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 1, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 1, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 2, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 2, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 2, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 3, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 3, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 3, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 4, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 4, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 4, postcode: 'xxx', street: 'xxx', city: 'xxx'},
];
function groupingApiArr(arr) {
return arr.reduce((acc, cur) => {
const groupKey = `group-${cur.id}`
if (!acc[groupKey]) {
acc[groupKey] = []
}
acc[groupKey].push(cur)
return acc
}, {})
}
console.log(groupingApiArr(api_array))
api_array [
{id: 1, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 1, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 1, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 2, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 2, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 2, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 3, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 3, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 3, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 4, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 4, postcode: 'xxx', street: 'xxx', city: 'xxx'},
{id: 4, postcode: 'xxx', street: 'xxx', city: 'xxx'},
];
let result = [];
for (let i = 0; i < numberOfGroupsIWantToMake; i++) {
let newGroupArray = api_array.filter(obj => obj.id === i);
result.push(newGroupArray);
}
return result;
Note: this is A solution, but it's not as performant as we're going over the entire array n number of times.