在PHP中,您可以。。。
range(1, 3); // Array(1, 2, 3)
range("A", "C"); // Array("A", "B", "C")
也就是说,有一个函数可以通过传递上下限来获得一系列数字或字符。
JavaScript本机是否有内置的功能?如果没有,我将如何实施?
在PHP中,您可以。。。
range(1, 3); // Array(1, 2, 3)
range("A", "C"); // Array("A", "B", "C")
也就是说,有一个函数可以通过传递上下限来获得一系列数字或字符。
JavaScript本机是否有内置的功能?如果没有,我将如何实施?
当前回答
这里是一个范围函数的定义,它的行为与Python的范围类型完全相同,只是这个函数不是懒惰的。把它变成发电机应该很容易。
范围构造函数的参数必须是数字。如果省略step参数,则默认为1。如果省略了start参数,则默认为0。如果步骤为零,则会引发错误。
range = (start, stop, step=1) => {
if(step === 0) throw new Error("range() arg 3 must not be zero");
const noStart = stop == null;
stop = noStart ? start : stop;
start = noStart ? 0 : start;
const length = Math.ceil(((stop - start) / step));
return Array.from({length}, (_, i) => (i * step) + start);
}
console.log(range(-10, 10, 2));
//output [Array] [-10,-8,-6,-4,-2,0,2,4,6,8]
console.log(range(10));
// [Array] [0,1,2,3,4,5,6,7,8,9]
console.log(3, 12);
// [Array] [3,4,5,6,7,8,9,10,11]
其他回答
为了在任何一个给定的数字可能更大的地方工作,我写了这样一个:
function getRange(start, end) {
return Array.from({
length: 1 + Math.abs(end - start)
}, (_, i) => end > start ? start + i : start - i);
}
在边界内生成整数数组的递归解决方案。
function intSequence(start, end, n = start, arr = []) {
return (n === end) ? arr.concat(n)
: intSequence(start, end, start < end ? n + 1 : n - 1, arr.concat(n));
}
$> intSequence(1, 1)
<- Array [ 1 ]
$> intSequence(1, 3)
<- Array(3) [ 1, 2, 3 ]
$> intSequence(3, -3)
<- Array(7) [ 3, 2, 1, 0, -1, -2, -3 ]
标准的Javascript没有生成范围的内置函数。有几个javascript框架添加了对这些功能的支持,或者正如其他人所指出的那样,您可以一直使用自己的功能。
如果您想再次检查,确定的资源是ECMA-262标准。
根据我的理解:
JS的运行时环境不支持尾部调用优化。编写任何递归函数来生成一个大范围的函数都会给你带来麻烦。如果我们要处理大量数据,那么创建循环数组可能不是最好的做法。写入大循环会导致事件队列变慢。
function range(start, end, step = 1) {
const _range = _start => f => {
if (_start < end) {
f(_start);
setTimeout(() => _range(_start + step)(f), 0);
}
}
return {
map: _range(start),
};
}
range(0, 50000).map(console.log);
此函数不会引发上述问题。
我刚刚通过Object.defineProperty在Array上创建了这个polyfill,以创建整数或字符串的范围。Object.defineProperty是创建polyfills的一种更安全的方法。
更安全的polyfill
if (!Array.range) {
Object.defineProperty(Array, 'range', {
value: function (from, to, step) {
if (typeof from !== 'number' && typeof from !== 'string') {
throw new TypeError('The first parameter should be a number or a character')
}
if (typeof to !== 'number' && typeof to !== 'string') {
throw new TypeError('The second parameter should be a number or a character')
}
var A = []
if (typeof from === 'number') {
A[0] = from
step = step || 1
while (from + step <= to) {
A[A.length] = from += step
}
} else {
var s = 'abcdefghijklmnopqrstuvwxyz'
if (from === from.toUpperCase()) {
to = to.toUpperCase()
s = s.toUpperCase()
}
s = s.substring(s.indexOf(from), s.indexOf(to) + 1)
A = s.split('')
}
return A
}
})
} else {
var errorMessage = 'DANGER ALERT! Array.range has already been defined on this browser. '
errorMessage += 'This may lead to unwanted results when Array.range() is executed.'
console.log(errorMessage)
}
示例
Array.range(1, 3)
// Return: [1, 2, 3]
Array.range(1, 3, 0.5)
// Return: [1, 1.5, 2, 2.5, 3]
Array.range('a', 'c')
// Return: ['a', 'b', 'c']
Array.range('A', 'C')
// Return: ['A', 'B', 'C']
Array.range(null)
Array.range(undefined)
Array.range(NaN)
Array.range(true)
Array.range([])
Array.range({})
Array.range(1, null)
// Return: Uncaught TypeError: The X parameter should be a number or a character