I have been using reduce()
method to group by Open and Closes statuses (Status_111
, Status_222
, etc) which then creates an array of which Ids (item.Id
) it is associated with.
Code is working and with an expected result, however, I feel like code could have been written better because as you can see I have been using too many if conditions for creating blank arrays to check if (item.Open && !obj[item.Open])
and if (item.Close && !obj[item.Close])
exists - how would you improve the code?
const items = [
{ Id: 100, Open: 'Status_111', Close: 'Status_111' },
{ Id: 200, Open: 'Status_111', Close: 'Status_222' },
{ Id: 300, Open: 'Status_333', Close: 'Status_444' }
]
function groupByOpenAndClose(items) {
return items.reduce(function (obj, item) {
if (item.Open && !obj[item.Open]) {
obj[item.Open] = {
Open: [],
Close: []
}
}
if (item.Close && !obj[item.Close]) {
obj[item.Close] = {
Open: [],
Close: []
}
}
if (obj[item.Open]) {
obj[item.Open].Open.push(item.Id)
}
if (obj[item.Close]) {
obj[item.Close].Close.push(item.Id)
}
return obj
}, {});
}
console.log(groupByOpenAndClose(items));
1 Answer 1
Like this:
function groupByOpenAndClose(items) {
return items.reduce((obj, item) => {
return {
...obj,
[item.Close]: {
Close: [...(obj[item.Close]?.Close ?? []), item.Id],
Open: obj[item.Close]?.Open ?? []
},
[item.Open]: {
Open: [...(obj[item.Open]?.Open ?? []), item.Id],
Close: obj[item.Open]?.Close ?? []
}
}
}, {});
}
But in all seriousness, it is not much you can do without creating some structure of your own - something like default dict in python:
class DefaultDict {
constructor(defFactory) {
this.defFactory = defFactory;
this.dict = {}
}
getOrDefault(status) {
if(!status) return;
if(!this.dict[status]) this.dict[status] = this.defFactory();
return this.dict[status];
}
}
function groupByOpenAndClose(items) {
return items.reduce(function(obj, item) {
obj.getOrDefault(item.Close)?.Close.push(item.Id);
obj.getOrDefault(item.Open)?.Open.push(item.Id);
return obj;
}, new DefaultDict(() => ({ Close: [], Open: [] })));
}
console.log(groupByOpenAndClose(items).dict);