我在不使用下划线的情况下使用此功能,但作为额外的挑战,我尝试使用下划线将罗马数字转换为阿拉伯数字。以下是我的尝试。它起作用,除了" next"数字大于"当前"一。我真的不确定原因,但是当我检查if(下一个> = num)时,if if是否甚至没有被执行?
var DIGIT_VALUES = {
I: 1,
V: 5,
X: 10,
L: 50,
C: 100,
D: 500,
M: 1000
};
var translateRomanNumeral = function(roman) {
// if it's not in the digit values object, return null
for (var i = 0; i < roman.length; i++) {
if (!(roman[i] in DIGIT_VALUES)) {
return null;
}
}
//with underscore:
var romanTranslated = reduce(roman, function(memo, letter, i) {
var prev = DIGIT_VALUES[roman[i - 1]];
var num = DIGIT_VALUES[letter];
var next = DIGIT_VALUES[roman[i + 1]];
if (next === undefined || next <= num) {
return memo + num;
}
由于某种原因,这不会被执行:
if (next >= num) {
var diff = num - prev;
console.log(diff);
return memo + (diff - prev);
}
}, 0);
// grab the first one
//1
// console.log(num);
return romanTranslated;
};
console.log(translateRomanNumeral("LXIV")); //returns 66 ---> should return 64
console.log(translateRomanNumeral("CI")); //working --> returns 101
console.log(translateRomanNumeral("MMMMCCL")); // working ---> returns 4250.
//works!
答案 0 :(得分:1)
您可以使用Array#reduce
的简洁版本,并查看实际值和下一个值。
function parseRoman(s) {
var val = { M: 1000, D: 500, C: 100, L: 50, X: 10, V: 5, I: 1 };
return s.toUpperCase().split('').reduce(function (r, a, i, aa) {
return r + (val[a] < val[aa[i + 1]] ? -val[a] : val[a]);
}, 0);
}
console.log(parseRoman("LXIV")); // 64
console.log(parseRoman("IX")) // 9
console.log(parseRoman("IV")) // 4
console.log(parseRoman("CI")); // 101
console.log(parseRoman("MMMMCCL")); // 4250
&#13;
答案 1 :(得分:0)
我的错误的主要来源是我定义reduce的方式不允许我在迭代时访问索引。我更新了我的reduce函数,然后在稍微调试之后就可以了:
var DIGIT_VALUES = {
I: 1,
V: 5,
X: 10,
L: 50,
C: 100,
D: 500,
M: 1000
};
var each = function(collection, iterator) {
if (Array.isArray(collection)) {
for (var i = 0; i < collection.length; i++) {
iterator(collection[i], i, collection);
}
} else {
for (var key in collection) {
iterator(collection[key], key, collection);
}
}
};
var reduce = function(collection, iterator, total) {
if (total == undefined) {
total = collection.shift();
}
each(collection, function(val, i) {
total = iterator(total, val, i);
})
return total;
};
var translateRomanNumeral = function(roman) {
if (typeof(roman) !== 'string') {
return null;
}
if (!roman) {
return 0;
}
// if it's not in the digit values object, return null
for (var i = 0; i < roman.length; i++) {
if (!(roman[i] in DIGIT_VALUES)) {
return null;
}
}
//with underscore:
return reduce(roman, function(memo, letter, i) {
var num = DIGIT_VALUES[letter];
//console.log(i);
//how do you acess the next item in a collection in reduce?
var next = DIGIT_VALUES[roman[Number(i) + 1]];
// console.log(Number(i) + 1);
// console.log(next);
if ( next === undefined || next <= num) {
return memo + num;
//console.log(memo);
}
else {
// var diff = num - prev;
// console.log(diff);
return memo - num;
// memo = memo + (next - num);
}
// return memo;
}, 0);
};
console.log(translateRomanNumeral("LXIV")); //returns 66 ---> should return 64
console.log(translateRomanNumeral("IX")) // should return 9
console.log(translateRomanNumeral("IV")) /// should return 4
console.log(translateRomanNumeral("CI"));
//working --> returns 101
console.log(translateRomanNumeral("MMMMCCL"));
// working ---> returns 4250.
//works!