使用给定的数字范围初始化JavaScript数组
数组初始化可以被认为是一项基本的JavaScript技能。不幸的是,JavaScript缺少一些其他语言具有的内置功能,比如Python的range()函数。让我们深入研究一下如何构建一个JavaScript的等价方法。
[!NOTE]
所有在这里介绍的方法都会生成一个包含
start(包含)但不包含end(不包含)的数组,以保持与Python的range()方法的一致性。如果要包含end值,您需要相应地修改length公式和映射函数。
使用数字范围初始化数组
我们可以使用Array.from()来创建一个新数组。我们需要事先知道数组的length,这可以从我们想要包含的数字范围计算出来。
数组的length的一般公式是(end - start) / step。所有三个值都作为函数参数提供。为了确保length是一个整数,我们将使用Math.ceil()来向上取整结果。
const range = (end, start = 0, step = 1) =>
Array.from(
{ length: Math.ceil((end - start) / step) },
(_, i) => i * step + start
);
range(5); // [0, 1, 2, 3, 4]
range(7, 3); // [3, 4, 5, 6]
range(9, 0, 2); // [0, 2, 4, 6, 8]
使用反向数字范围初始化数组
如果您想要一个反向范围,您可能会尝试在上一个代码片段的结果上使用Array.prototype.reverse()。然而,这相对低效,因为它需要两次遍历整个数组。
相反,我们可以修改上面代码片段的映射函数来得到所需的结果,通过反向迭代给定的范围。为了做到这一点,我们需要将start替换为end,并取反step的值。
const rangeReverse = (end, start = 0, step = 1) =>
Array.from(
{ length: Math.ceil((end - start) / step) },
(_, i) => i * -step + end
);
rangeReverse(5); // [5, 4, 3, 2, 1]
rangeReverse(7, 3); // [7, 6, 5, 4]
rangeReverse(9, 0, 2); // [9, 7, 5, 3, 1]
通用的range()函数,与Python的签名匹配
拥有两个稍微不同用途的函数并不罕见,但我们可以将解决方案推广到根据提供的参数推断正确的行为。对于反向范围,我们只需提供一个负的step值。
另一个改进是匹配Python的range()签名。这样我们可以提供(end)、(start, end)或(start, end, step)作为参数。注意第一个和第二个参数的顺序变化。为了实现这一点,我们将放弃参数的默认值,并使用条件语句来检查提供的参数数量。
const range = (start, end, step) => {
if (end === undefined) [end, start] = [start, 0];
if (step === undefined) step = start < end ? 1 : -1;
return Array.from(
{ length: Math.ceil((end - start) / step) },
(_, i) => i * step + start
);
};
// 正步长值
range(5); // [0, 1, 2, 3, 4]
range(3, 7); // [3, 4, 5, 6]
range(0, 9, 2); // [0, 2, 4, 6, 8]
// 负步长值
range(5, 0, -1); // [5, 4, 3, 2, 1]
range(7, 3); // [7, 6, 5, 4]
range(9, 0, -2); // [9, 7, 5, 3, 1]