在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本机是否有内置的功能?如果没有,我将如何实施?
当前回答
我的实施
export function stringRange(a: string, b: string) {
let arr = [a + ''];
const startPrefix = a.match(/([\D])+/g);
const endPrefix = b.match(/([\D])+/g);
if ((startPrefix || endPrefix) && (Array.isArray(startPrefix) && startPrefix[0]) !== (Array.isArray(endPrefix) && endPrefix[0])) {
throw new Error('Series number does not match');
}
const startNum = a.match(/([\d])+/g);
const endNum = b.match(/([\d])+/g);
if (!startNum || !endNum) {
throw new Error('Range is not valid');
}
let start = parseInt(startNum[0], 10);
let end = parseInt(endNum[0], 10);
if (start > end) {
throw new Error('Ending value should be lessesr that starting value');
}
while (start !== end) {
start++;
arr.push(startPrefix ? startPrefix[0] + (start + '').padStart(startNum[0].length, '0') : start + '');
}
return arr;
}
样本结果
// console.log(range('0', '10'));
// console.log(range('10', '10'));
// console.log(range('10', '20'));
// console.log(range('10', '20000'));
// console.log(range('ABC10', 'ABC23'));
// console.log(range('ABC10', 'ABC2300'));
// console.log(range('ABC10', 'ABC09')); --> Failure case
// console.log(range('10', 'ABC23')); --> Failure case
// console.log(range('ABC10', '23')); --> Failure case
其他回答
我的实施
export function stringRange(a: string, b: string) {
let arr = [a + ''];
const startPrefix = a.match(/([\D])+/g);
const endPrefix = b.match(/([\D])+/g);
if ((startPrefix || endPrefix) && (Array.isArray(startPrefix) && startPrefix[0]) !== (Array.isArray(endPrefix) && endPrefix[0])) {
throw new Error('Series number does not match');
}
const startNum = a.match(/([\d])+/g);
const endNum = b.match(/([\d])+/g);
if (!startNum || !endNum) {
throw new Error('Range is not valid');
}
let start = parseInt(startNum[0], 10);
let end = parseInt(endNum[0], 10);
if (start > end) {
throw new Error('Ending value should be lessesr that starting value');
}
while (start !== end) {
start++;
arr.push(startPrefix ? startPrefix[0] + (start + '').padStart(startNum[0].length, '0') : start + '');
}
return arr;
}
样本结果
// console.log(range('0', '10'));
// console.log(range('10', '10'));
// console.log(range('10', '20'));
// console.log(range('10', '20000'));
// console.log(range('ABC10', 'ABC23'));
// console.log(range('ABC10', 'ABC2300'));
// console.log(range('ABC10', 'ABC09')); --> Failure case
// console.log(range('10', 'ABC23')); --> Failure case
// console.log(range('ABC10', '23')); --> Failure case
这里是一个范围函数的定义,它的行为与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]
您可以使用lodash或Undescore.js范围:
var range = require('lodash/range')
range(10)
// -> [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
或者,如果您只需要连续的整数范围,则可以执行以下操作:
Array.apply(undefined, { length: 10 }).map(Number.call, Number)
// -> [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
在ES6范围内,可使用发电机实现:
function* range(start=0, end=null, step=1) {
if (end == null) {
end = start;
start = 0;
}
for (let i=start; i < end; i+=step) {
yield i;
}
}
这种实现在迭代大型序列时节省了内存,因为它不必将所有值具体化为数组:
for (let i of range(1, oneZillion)) {
console.log(i);
}
使用范围([start,]stop[,step])签名完成ES6实现:
function range(start, stop, step=1){
if(!stop){stop=start;start=0;}
return Array.from(new Array(int((stop-start)/step)), (x,i) => start+ i*step)
}
如果要自动负步进,请添加
if(stop<start)step=-Math.abs(step)
或者更简单地说:
range=(b, e, step=1)=>{
if(!e){e=b;b=0}
return Array.from(new Array(int((e-b)/step)), (_,i) => b<e? b+i*step : b-i*step)
}
如果你有巨大的射程,看看保罗·莫雷蒂的发电机方法
也可以使用生成器生成序列。不同之处在于序列中的每个值都是延迟加载的。spread运算符和for为结果工作。星号符号使函数成为生成器。
const range = function*(from,to) {
for(let i = from; i <= to; i++) yield I;
};
[...range(3,5)]// => [3, 4, 5]