I am surprised why a boolean value is being appended to the current value in my reduce functionality.
var romanToInt = function (s) {
const DICT = {
I: 1,
V: 5,
X: 10,
L: 50,
C: 100,
D: 500,
M: 1000,
}
let reversedArr = s.split('').reverse()
reversedArr
return reversedArr.reduce((sum, cur, i, arr) => {
let value = DICT[cur]
// check if preceeding numeral subtracts
if ((arr[i] = arr[i - 1] === 'VI') && i != 0) {
sum -= value
} else {
// Set sum as the first
sum = value
}
return sum
}, 0)
}
console.log(romanToInt('III'))
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
Why is this expression (curr = arr[i - 1] === 'VI')
evaluating to false, true, true?
The value of curr after three iterations is Ifalse, Ifalse, Ifalse
. How is this happening?
All I want to do is check wheather or not the current value and the preceding value equals the string 'VI'
CodePudding user response:
x = y
is equivalent to x = x y
, and that whole assignment expression evaluates to the value on the right-hand-side: the x y
. If x y
is truthy, the whole resulting expression will be truthy.
For the same reason, your
if ((arr[i] = arr[i - 1] === 'VI') && i != 0) {
isn't doing what you're thinking it is.
It looks like you don't need to assign to the array index at all here - just compare there, and if the condition is fulfilled, change the sum
(without changing anything else inside the loop).
var romanToInt = function (s) {
const DICT = {
I: 1,
V: 5,
X: 10,
L: 50,
C: 100,
D: 500,
M: 1000,
}
const reversedArr = s.split('').reverse();
return reversedArr.reduce((sum, cur, i, arr) => {
let value = DICT[cur]
// check if preceeding numeral subtracts
if ((arr[i] arr[i - 1] === 'VI') && i != 0) {
sum -= value
} else {
// Set sum as the first
sum = value
}
return sum
}, 0)
}
console.log(romanToInt('III'))
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
But you still have a ways to go to fix the rest of your algorithm. This is a good approach.
CodePudding user response:
shorter version ;)
const
DICT = { I: 1, V: 5, X: 10, L: 50, C: 100, D: 500, M: 1000 }
, Narr = [ 'IV','IX', 'XL', 'XC', 'CD', 'CM' ]
;
const romanToInt = s =>
[...s].reverse().reduce((sum, curr, i, {[i-1]:prev}) =>
sum (Narr.includes(`${curr}${prev}`) ? -DICT[curr] : DICT[curr]) , 0)
console.log('III', romanToInt('III'))
console.log('IV', romanToInt('IV'))
console.log('VII', romanToInt('VII'))
console.log('IX', romanToInt('IX'))
<iframe name="sif3" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>