在此 js 代码片段中使用 break 语句是一种好习惯吗?
Is it good practice to use a break statement in this js code snippet?
此函数的目的是根据给定的航空公司费率 table(参数 1)和重量(参数 2)计算价格(结果)。 rates 数组中的数组行表示:[weight break, rate/kg, breakpoint].
计算示例:
- 检查给定的重量是否低于重量限制 (
wb
),应用最低费率,即 wb * rate
;
- 如果不是,检查权重是否低于断点(
bp
),计算weight * rate
;
- 如果权重高于
bp
,应用下一个数组的 wb
乘以下一个数组的比率。
注意:费率 table 的最后一行没有 bp
。这就是这些 table 的提供方式。
TLDR:
我的代码工作得很好(见下文),但我对此很陌生,我想知道是否有更好的方法来编写这个小算法。我发现了递归,但我不确定如何编写递归函数。也许这可以用更简洁的方式编写?我问这个问题是为了更好地编码。谢谢!
rates = [
[ 45, 3.8, 88 ],
[ 100, 3.35, 296 ],
[ 300, 3.3, 492 ],
[ 500, 3.25]
];
function calcPrice(arr, weight) {
let price = 0;
for (let i = 0; i < arr.length; i++) {
if (weight <= arr[i][0]) {
price = arr[i][0] * arr[i][1]; break;
} else if (weight <= arr[i][2] && arr[i][2] !== undefined) {
price = weight * arr[i][1]; break;
} else {
price = weight * arr[i][1];
}
}
return price;
}
console.log(calcPrice(rates, 89);
我认为有几种方法可以使它更简洁易读。这真的只是一些小事。
第一个是 JavaScript 技巧,称为 destructuring assignment。这将允许您为数组中的值指定变量名称,如下所示:
const [weightBreak, rate, breakpoint] = arr[i];
然后这个:arr[i][0] * arr[i][1]
变成 weightBreak * rate
。
另一件小事是格式化(可能只需要将其输入到本网站)。即使它看起来微不足道,正确格式化您的代码对提高可读性也有很大帮助。
最后一件事:如果我们在 arr
中的 weight <= arr[i][0]
或 weight <= arr[i][2]
中找不到任何项目,那么看起来可以在每次迭代中调用 else 块。在这种情况下,我们返回的是基于 arr
中最后一项的值。如果我们使用早期的 return
语句而不是 break
语句,我们可以将该部分完全从循环中拉出来。
如果我们将所有这些放在一起,那么我们得到:
function calcPrice(arr, weight) {
for (let i = 0; i < arr.length; i++) {
const [weightBreak, rate, breakpoint] = arr[i];
if (weight <= weightBreak) {
return weightBreak * rate;
}
if (weight <= breakpoint && breakpoint !== undefined) {
return weight * rate;
}
}
const lastItem = arr[arr.length - 1];
return weight * lastItem[1];
}
如果您希望我澄清其中任何一个,请随时提问!希望对您有所帮助,祝您编码愉快!
这是用 recursion 标记的,我认为这是一个有用的调用。使用解构和默认参数的此函数的递归版本最终变得非常简单:
const calcPrice = ([[wb, rate, bp = Infinity], ...rates], weight = 0) =>
weight < bp
? rate * Math .max (wb, weight)
: calcPrice (rates, weight);
const rates = [[45, 3.8, 88], [100, 3.35, 296], [300, 3.3, 492], [500, 3.25]];
const vals = [33, 47, 85, 90, 103, 296, 297, 302, 490, 497, 2001]
vals .forEach (v => console .log (`${v} : ${calcPrice(rates, v).toFixed(2)}`))
请注意,通过将断点默认设置为 Infinity
,我们可以避免对是否存在第三个条目进行任何特殊检查。此外,关于如何进行实际计算的逻辑被简化了,注意我们只需要与断点进行比较,使用 max
选择要与我们的速率相乘的值。所以如果权重小于断点,我们可以returnrate * Math .max (wb, weight)
。如果不是,那么我们重复数组的剩余元素。
另外,您的标题询问了break
语句的使用。我认为你的直觉是正确的;这些应该很少见。他们通常会指出经过严格重构后可能表现良好的代码。除了上面的递归技术之外,您还可以使用 const [wp, rate, bp = Infinity] = rates.find(([ , , bp]) => weight <= bp)
之类的方法来管理它。这也将避免 break
语句以及显式 for
-loop.
更新
通过谨慎使用默认参数,此版本携带更多 error-correction:
const calcPrice = (
[[weightbreak = 0, rate = 0, breakpoint = Infinity] = [0, 0, Infinity], ...rates] = [],
weight = 0
) =>
weight < breakpoint
? rate * Math .max (weightbreak, weight)
: calcPrice (rates, weight);
如果 rates
的数组不存在,或者它为空,或者缺少某些值,它不会抛出错误。相反,在大多数情况下,它将 return 归零。它将处理任何 weight
,再次使用 Infinity
捕获尚未匹配的大值。
此函数的目的是根据给定的航空公司费率 table(参数 1)和重量(参数 2)计算价格(结果)。 rates 数组中的数组行表示:[weight break, rate/kg, breakpoint].
计算示例:
- 检查给定的重量是否低于重量限制 (
wb
),应用最低费率,即wb * rate
;
- 如果不是,检查权重是否低于断点(
bp
),计算weight * rate
; - 如果权重高于
bp
,应用下一个数组的wb
乘以下一个数组的比率。
注意:费率 table 的最后一行没有 bp
。这就是这些 table 的提供方式。
TLDR:
我的代码工作得很好(见下文),但我对此很陌生,我想知道是否有更好的方法来编写这个小算法。我发现了递归,但我不确定如何编写递归函数。也许这可以用更简洁的方式编写?我问这个问题是为了更好地编码。谢谢!
rates = [
[ 45, 3.8, 88 ],
[ 100, 3.35, 296 ],
[ 300, 3.3, 492 ],
[ 500, 3.25]
];
function calcPrice(arr, weight) {
let price = 0;
for (let i = 0; i < arr.length; i++) {
if (weight <= arr[i][0]) {
price = arr[i][0] * arr[i][1]; break;
} else if (weight <= arr[i][2] && arr[i][2] !== undefined) {
price = weight * arr[i][1]; break;
} else {
price = weight * arr[i][1];
}
}
return price;
}
console.log(calcPrice(rates, 89);
我认为有几种方法可以使它更简洁易读。这真的只是一些小事。
第一个是 JavaScript 技巧,称为 destructuring assignment。这将允许您为数组中的值指定变量名称,如下所示:
const [weightBreak, rate, breakpoint] = arr[i];
然后这个:arr[i][0] * arr[i][1]
变成 weightBreak * rate
。
另一件小事是格式化(可能只需要将其输入到本网站)。即使它看起来微不足道,正确格式化您的代码对提高可读性也有很大帮助。
最后一件事:如果我们在 arr
中的 weight <= arr[i][0]
或 weight <= arr[i][2]
中找不到任何项目,那么看起来可以在每次迭代中调用 else 块。在这种情况下,我们返回的是基于 arr
中最后一项的值。如果我们使用早期的 return
语句而不是 break
语句,我们可以将该部分完全从循环中拉出来。
如果我们将所有这些放在一起,那么我们得到:
function calcPrice(arr, weight) {
for (let i = 0; i < arr.length; i++) {
const [weightBreak, rate, breakpoint] = arr[i];
if (weight <= weightBreak) {
return weightBreak * rate;
}
if (weight <= breakpoint && breakpoint !== undefined) {
return weight * rate;
}
}
const lastItem = arr[arr.length - 1];
return weight * lastItem[1];
}
如果您希望我澄清其中任何一个,请随时提问!希望对您有所帮助,祝您编码愉快!
这是用 recursion 标记的,我认为这是一个有用的调用。使用解构和默认参数的此函数的递归版本最终变得非常简单:
const calcPrice = ([[wb, rate, bp = Infinity], ...rates], weight = 0) =>
weight < bp
? rate * Math .max (wb, weight)
: calcPrice (rates, weight);
const rates = [[45, 3.8, 88], [100, 3.35, 296], [300, 3.3, 492], [500, 3.25]];
const vals = [33, 47, 85, 90, 103, 296, 297, 302, 490, 497, 2001]
vals .forEach (v => console .log (`${v} : ${calcPrice(rates, v).toFixed(2)}`))
请注意,通过将断点默认设置为 Infinity
,我们可以避免对是否存在第三个条目进行任何特殊检查。此外,关于如何进行实际计算的逻辑被简化了,注意我们只需要与断点进行比较,使用 max
选择要与我们的速率相乘的值。所以如果权重小于断点,我们可以returnrate * Math .max (wb, weight)
。如果不是,那么我们重复数组的剩余元素。
另外,您的标题询问了break
语句的使用。我认为你的直觉是正确的;这些应该很少见。他们通常会指出经过严格重构后可能表现良好的代码。除了上面的递归技术之外,您还可以使用 const [wp, rate, bp = Infinity] = rates.find(([ , , bp]) => weight <= bp)
之类的方法来管理它。这也将避免 break
语句以及显式 for
-loop.
更新
通过谨慎使用默认参数,此版本携带更多 error-correction:
const calcPrice = (
[[weightbreak = 0, rate = 0, breakpoint = Infinity] = [0, 0, Infinity], ...rates] = [],
weight = 0
) =>
weight < breakpoint
? rate * Math .max (weightbreak, weight)
: calcPrice (rates, weight);
如果 rates
的数组不存在,或者它为空,或者缺少某些值,它不会抛出错误。相反,在大多数情况下,它将 return 归零。它将处理任何 weight
,再次使用 Infinity
捕获尚未匹配的大值。