I have a class with a property of grid[][]
and each value is either true or false. I need to convert this to a string with letters o and b in place of the boolean.
First way, simple for loops over the array and return the string:
get rle() {
let result = "";
for(let y = 0; y < this.grid.length; y++) {
for(let x =0; x < this.grid[y].length; x++) {
result += ( (this.grid[y][x]) ? "o" : "b" );
}
}
return result;
}
Or a more JS style solution?
get rle() {
return this.grid.reduce( (total, currentValue, currentIndex, arr) => {
return total + arr[currentIndex].reduce( (total, currentValue, currentIndex, arr) => {
return total + ( (arr[currentIndex]) ? "o" : "b" );
}, "");
}, "");
}
Is this a good JS style solution, and what in your opinion is better? I prefer the first because anyone can instantly understand it. The JS solution makes me frown with 3 nested returns, looks odd.
1 Answer 1
First, a few points of the code you wrote. If you have an array of values, you can join
the values together to efficiently create a string. This would eliminate the need for at least one of the reduce
calls. Second, in a reduce call, the value of the second callback parameter (currentValue
in your code) is the value of the array parameter at the index parameter (arr[currentIndex]
in your code). Combining that with Javascript's capability to ignore excess function parameters, your reduce
calls should take only two parameters, and use the currentValue
in place of the arr[currentIndex]
.
You should also avoid using the same variable names in the same scope. Having two sets of total
, currentValue
, currentIndex
, and arr
could get confusing quickly, and lead to strange bugs.
Now, for the one-liner:
return this.grid.flat().map((el) => el ? "o" : "b").join("");
See Array#flat
, Array#map
, and the aforementioned Array#join
. Of these, Array#flat
is the newest and possibly unsupported method. It can be easily polyfilled or replaced. The MDN page shows some clever replacements like arr.reduce((all, row) => all.concat(row), [])
and [].concat(...arr)
.
-
\$\begingroup\$ Yes, And this method will work faster too... \$\endgroup\$Phantom– Phantom2019年02月11日 12:11:25 +00:00Commented Feb 11, 2019 at 12:11
-
\$\begingroup\$ That's the one liner I was looking for. Back to the arrays manual for me.. thanks cbojar. \$\endgroup\$Matthew Page– Matthew Page2019年02月11日 12:47:16 +00:00Commented Feb 11, 2019 at 12:47