使用给定的数字范围初始化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]