2
\$\begingroup\$

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));

asked Dec 6, 2021 at 22:39
\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

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);
answered Dec 7, 2021 at 18:56
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.