In this article, I try to suggest effective solutions with objects in JavaScript for common use cases in the real world.
Objects instead of array search
Using objects in an array search decreases the time complexity of your solution in quite a lot of cases. Let’s continue explaining with examples:
function findMaxOccured() {
const list = [12, 3, 55, 2, 7, 9, 2, 4, 2, 3];
let maxOcc = { value: '', times: 0 };
for (let i of list) {
// this filter is a nested loop actually!
const occ = list.filter(el => el === i).length;
if (occ > maxOcc.times) {
maxOcc = { value: i, times: occ };
}
}
return maxOcc;
}
In the example above, we find the max occurred element in the list. There is a nested loop in here (filter method) because we are searching the whole list to find the occurrence times for each element of the list. So, the time complexity is O(n²) for this solution which is not good enough!
The possible object-related approach can be below:
function findMaxOccured() {
const list = [12, 3, 55, 2, 7, 9, 2, 4, 2, 3];
const occMap = {};
let maxOcc = { value: '', times: 0 };
for (let i of list) {
occMap[i] = (occMap[i] || 0) + 1;
}
for (let i of Object.keys(occMap)) {
if (occMap[i] > maxOcc.times) {
maxOcc = { value: i, times: occMap[i] };
}
}
return maxOcc;
}
First, we generate an occurrence map for the list. Then find the max occurred element in the map by iterating through it. Here there is no nested loop so time complexity is O(n) which is better!
Objects instead of conditions
In some cases, we need to call different functions or assign different values according to the value of a variable. For these cases, using a matching object instead of several condition blocks can be more effective solutions.
Let’s give an example:
The following code block is the first thing that comes to mind mostly.
function conditional(param) {
if (param === 'a') {
return 1;
} else if (param === 'b' || param === 'c') {
return 2;
} else {
return 3;
}
}
This can be refactored like below:
function objectMatch(param) {
const match = {
a: 1,
b: 2,
c: 2,
default: 3
};
return match[param] || match.default;
}
This alternative also is conceivable for switch cases:
function conditional(param) {
switch (param) {
case 'a':
func1();
break;
case 'b':
case 'c':
func2();
break;
default:
func3();
break;
}
}
In addition to the first one, we need to call the function ()
after getting from the mapping object. Again my suggestion:
function objectMatch(param) {
const match = {
a: func1,
b: func2,
c: func2,
default: func3
};
const correspondingFunc = match[param] || match.default;
correspondingFunc();
}
Additionally, this mapping objects can be moved to a higher scope if it doesn’t need to change in function just like our examples. Of course, for more complex conditions this approach couldn’t be the best fit but for simple cases like my examples, you can consider using objects.
The examples can be increased but I hope these explain the main idea.
Top comments (0)