我有一个针对quantity range: price
数组检查数字(数量)的功能
var data = {
"1 - 4": " $4.25 ",
"10 - 24": " $3.25 ",
"25 - 49": " $3.04 ",
"5 - 9": " $3.51 ",
"50+": " $2.84 "
}
function get_price(arr, val) {
var price = Object.keys(arr).reduce((a, c) => {
var s = c.trim();
if (/\d+\-\d+/.test(s)) {
var range = s.split("-");
if (val >= parseInt(range[0]) && val <= parseInt(range[1])) {
a = arr[c];
}
} else {
s = s.replace(/\D/g, "");
if (val >= s) {
a = arr[c];
}
}
return a;
}, 0);
return price;
}
问题是,如果数字大于50但小于100,则表示计算正确;超过100,则无法看到50+并使用该价格。
感谢您的帮助!
答案 0 :(得分:5)
使用字符串作为对象的键,可以很好地工作:
const range = {
"1-4": " $4.25 ",
"10-24": " $3.25 ",
"25-49": " $3.04 ",
"5-9": " $3.51 ",
"50+": " $2.84 "
}
有关property accessors的更多信息:
在此代码中,属性必须是有效的JavaScript标识符,即,一个字母数字字符序列,还包括不能以数字开头的下划线(
"_"
)和美元符号("$"
)。 。例如,object.$1
有效,而object.1
无效。
演示:
function get_price(arr, val) {
var price = Object.keys(arr).reduce((a, c) => {
var s = c.trim();
if (/\d+\-\d+/.test(s)) {
var range = s.split("-");
if (val >= parseInt(range[0]) && val <= parseInt(range[1])) {
a = arr[c];
}
} else {
s = s.replace(/\D/g, "");
if (val >= s) {
a = arr[c];
}
}
return a;
}, 0);
return price;
}
const range = {
"1-4": " $4.25 ",
"10-24": " $3.25 ",
"25-49": " $3.04 ",
"5-9": " $3.51 ",
"50+": " $2.84 "
}
console.log(get_price(range, 60))
console.log(get_price(range, 500))
答案 1 :(得分:1)
仅当您将字符串作为参数val
传递给get_price
时,您的代码才会起作用,因为它将对假设"100" > "50"
之间的字符串进行比较,并且将失败。
确定要转换为数字
if (+val >= +s) {
a = arr[c];
}
和
if (+val >= parseInt(range[0]) && +val <= parseInt(range[1])) {
a = arr[c];
}
答案 2 :(得分:0)
我有一些不同的方法。我假设范围列表很可能会被重用。此解决方案使用的函数将'25 - 49'
转换为{start: 25, end: 49}
,并使用该函数创建对象数组,例如{start: 25, end: 49, value: '$3.04'}
。然后,我返回一个在该数组上关闭的函数,该函数接受一个价格并返回包含该价格的第一个范围的值。
这具有不连续解析范围字符串的优点(可能很小)。更重要的是,它将问题分解成几个可重用的部分。 makeRange
可能在项目中的其他地方重用,findByRange
也可能被重用。特定于当前需求的唯一部分是getPrice
,这变得相当明确。
const makeRange = (desc, match = '') =>
((match = desc.match(/(\d+)\s*\-\s*(\d+)/)) && match && {start: Number(match[1]), end: Number(match[2])})
|| ((match = desc.match(/(\d+)\s*\+/)) && match && {start: Number(match[1]), end: Infinity})
|| ((match = desc.match(/<\s*(\d+)/)) && match && {start: -Infinity, end: Number(match[1]) - 1})
|| {start: NaN, end: NaN}
const findByRange = rangeValues => {
const ranges = Object.keys(rangeValues).map(
key => Object.assign({value: rangeValues[key]}, makeRange(key))
).sort((a, b) => a.start - b.start) // sorting mostly for cleanliness
return val => {
const range = ranges.find(range => range.start <= val && val <= range.end)
return range ? range.value : false // or throw an exception, or use default
}
}
const getPrice = findByRange({
'< 5' : ' $4.25 ', // could also be '1 - 4'
'5-9' : ' $3.51 ',
'10-24' : ' $3.25 ',
'25-49' : ' $3.04 ',
'50+' : ' $2.84 '
});
[3, 7, 16, 42, 57, 143].forEach(
n => console.log(`${n} --> ${getPrice(n)}`)
)