在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本机是否有内置的功能?如果没有,我将如何实施?
当前回答
对一些不同的范围函数进行了研究。检查执行这些函数的不同方法的jsperf比较。当然不是一个完美或详尽的列表,但应该有帮助:)
获胜者是。。。
function range(lowEnd,highEnd){
var arr = [],
c = highEnd - lowEnd + 1;
while ( c-- ) {
arr[c] = highEnd--
}
return arr;
}
range(0,31);
从技术上讲,它不是firefox上最快的,但铬合金上的疯狂速度差(imho)弥补了这一点。
还有一个有趣的观察是,与firefox相比,chrome使用这些阵列功能的速度要快得多。Chrome速度至少快4或5倍。
其他回答
要紧密复制的类型脚本函数
/**
* Create a generator from 0 to stop, useful for iteration. Similar to range in Python.
* See: https://stackoverflow.com/questions/3895478/does-javascript-have-a-method-like-range-to-generate-a-range-within-the-supp
* See: https://docs.python.org/3/library/stdtypes.html#ranges
* @param {number | BigNumber} stop
* @returns {Iterable<number>}
*/
export function range(stop: number | BigNumber): Iterable<number>
/**
* Create a generator from start to stop, useful for iteration. Similar to range in Python.
* See: https://stackoverflow.com/questions/3895478/does-javascript-have-a-method-like-range-to-generate-a-range-within-the-supp
* See: https://docs.python.org/3/library/stdtypes.html#ranges
* @param {number | BigNumber} start
* @param {number | BigNumber} stop
* @returns {Iterable<number>}
*/
export function range(
start: number | BigNumber,
stop: number | BigNumber,
): Iterable<number>
/**
* Create a generator from start to stop while skipping every step, useful for iteration. Similar to range in Python.
* See: https://stackoverflow.com/questions/3895478/does-javascript-have-a-method-like-range-to-generate-a-range-within-the-supp
* See: https://docs.python.org/3/library/stdtypes.html#ranges
* @param {number | BigNumber} start
* @param {number | BigNumber} stop
* @param {number | BigNumber} step
* @returns {Iterable<number>}
*/
export function range(
start: number | BigNumber,
stop: number | BigNumber,
step: number | BigNumber,
): Iterable<number>
export function* range(a: unknown, b?: unknown, c?: unknown): Iterable<number> {
const getNumber = (val: unknown): number =>
typeof val === 'number' ? val : (val as BigNumber).toNumber()
const getStart = () => (b === undefined ? 0 : getNumber(a))
const getStop = () => (b === undefined ? getNumber(a) : getNumber(b))
const getStep = () => (c === undefined ? 1 : getNumber(c))
for (let i = getStart(); i < getStop(); i += getStep()) {
yield i
}
}
使用Harmony生成器,除IE11外,所有浏览器都支持:
var take = function (amount, generator) {
var a = [];
try {
while (amount) {
a.push(generator.next());
amount -= 1;
}
} catch (e) {}
return a;
};
var takeAll = function (gen) {
var a = [],
x;
try {
do {
x = a.push(gen.next());
} while (x);
} catch (e) {}
return a;
};
var range = (function (d) {
var unlimited = (typeof d.to === "undefined");
if (typeof d.from === "undefined") {
d.from = 0;
}
if (typeof d.step === "undefined") {
if (unlimited) {
d.step = 1;
}
} else {
if (typeof d.from !== "string") {
if (d.from < d.to) {
d.step = 1;
} else {
d.step = -1;
}
} else {
if (d.from.charCodeAt(0) < d.to.charCodeAt(0)) {
d.step = 1;
} else {
d.step = -1;
}
}
}
if (typeof d.from === "string") {
for (let i = d.from.charCodeAt(0); (d.step > 0) ? (unlimited ? true : i <= d.to.charCodeAt(0)) : (i >= d.to.charCodeAt(0)); i += d.step) {
yield String.fromCharCode(i);
}
} else {
for (let i = d.from; (d.step > 0) ? (unlimited ? true : i <= d.to) : (i >= d.to); i += d.step) {
yield i;
}
}
});
示例
take
示例1。
尽可能多地索取
take(10,范围({从:100,步骤:5,到:120}))
回报
[100, 105, 110, 115, 120]
示例2。
不需要
take(10,范围({从:100,步骤:5}))
回报
[100, 105, 110, 115, 120, 125, 130, 135, 140, 145]
全部接受
示例3。
来自不必要的
takeAll(范围({到:5}))
回报
[0, 1, 2, 3, 4, 5]
示例4。
takeAll(范围({到:500,步骤:100}))
回报
[0, 100, 200, 300, 400, 500]
示例5。
takeAll(范围({从:“z”到:“a”}))
回报
[“z”、“y”、“x”、“w”、“v”、“u”、“t”、“s”、“r”、“q”、“p”、“o”、“n”、“m”、“l”、“k”、“j”、“i”、“h”、“g”、“f”、“e”、“d”、“c”、“b”、“a”]
虽然这不是来自PHP,而是对Python范围的模仿。
function range(start, end) {
var total = [];
if (!end) {
end = start;
start = 0;
}
for (var i = start; i < end; i += 1) {
total.push(i);
}
return total;
}
console.log(range(10)); // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
console.log(range(0, 10)); // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
console.log(range(5, 10)); // [5, 6, 7, 8, 9]
---更新(感谢@lokhmakov简化)---
另一个使用ES6发生器的版本(参见伟大的Paolo Moretti回答ES6发生器):
const RANGE = (x,y) => Array.from((function*(){
while (x <= y) yield x++;
})());
console.log(RANGE(3,7)); // [ 3, 4, 5, 6, 7 ]
或者,如果我们只需要可迭代,那么:
const RANGE_ITER = (x,y) => (function*(){
while (x <= y) yield x++;
})();
for (let n of RANGE_ITER(3,7)){
console.log(n);
}
// 3
// 4
// 5
// 6
// 7
---原始代码为:---
const RANGE = (a,b) => Array.from((function*(x,y){
while (x <= y) yield x++;
})(a,b));
and
const RANGE_ITER = (a,b) => (function*(x,y){
while (x <= y) yield x++;
})(a,b);
我很惊讶地看到了这条线索,并没有看到任何类似我的解决方案(也许我错过了答案),所以就在这里。我在ES6语法中使用了一个简单的范围函数:
// [begin, end[
const range = (b, e) => Array.apply(null, Array(e - b)).map((_, i) => {return i+b;});
但它只在向前计数时有效(即begin<end),因此我们可以在需要时对其进行轻微修改,如下所示:
const range = (b, e) => Array.apply(null, Array(Math.abs(e - b))).map((_, i) => {return b < e ? i+b : b-i;});