Reputation: 1554
Suppose I have a code like this:
function example() {
const obj = {};
for (let i = 0; i < 10; i++) {
for (let j = 0; j< 10; j++) {
if (obj[i] == undefined) {
obj[i] = 0;
}
if (obj[j] == undefined) {
obj[j] = 0;
} else {
obj[i] += i;
obj[j] += j;
}
}
}
}
Here you can see:
if (obj[i] == undefined) {
obj[i] = 0;
}
I check if i
not in obj
I assign the key i
inside obj
with 0 else I do nothing, I do sample with j
.
The code is duplicated and I do not want to repeat my self, it is bad practice so I make another function to apply for i
and j
like this:
function initObjWithValue(obj, keys) {
for (const key of keys) {
if (obj[key] === undefined) {
obj[key] = 0;
}
}
}
The function is very easy to understand right? It has first parameter as an object and the second parameter is an array of keys to check. Now I can refactor my code like this:
function example() {
const obj = {};
for (let i = 0; i < 10; i++) {
for (let j = 0; j< 10; j++) {
initObjWithValue(obj, [i, j]);
obj[i] += i;
obj[j] += j;
}
}
}
The code is clearer but as you can see in my function initObjWithValue
, it mutates obj
and I think it is not good. Here is the quote from Wiki page:
In computer programming, a pure function is a function that has the following properties: Its return value is the same for the same arguments (no variation with local static variables, non-local variables, mutable reference arguments or input streams from I/O devices).
And I got stuck at this point, how can I do not repeat my self and I can achieve pure function in this case?
Upvotes: 4
Views: 425
Reputation: 592
Instead of checking
(obj[i] == undefined)
write
(typeof obj[i] == undefined)
Upvotes: 0
Reputation: 50749
You could instead make initObjectWithValue
return a new object, which you can then merge with your current obj
. This way, all you're doing is reading from obj
, and not mutating it within initObjectWithValue
:
function initObjWithValue(obj, keys) {
const tmp = {};
for (const key of keys) {
if (!(key in obj)) {
tmp[key] = 0;
}
}
return tmp;
}
function example() {
const obj = {};
for (let i = 0; i < 10; i++) {
for (let j = 0; j< 10; j++) {
Object.assign(obj, initObjWithValue(obj, [i, j])); // merge the return with current object
obj[i] += i;
obj[j] += j;
}
}
return obj;
}
console.log(example());
Upvotes: 3