在PHP中,您可以。。。

range(1, 3); // Array(1, 2, 3)
range("A", "C"); // Array("A", "B", "C")

也就是说,有一个函数可以通过传递上下限来获得一系列数字或字符。

JavaScript本机是否有内置的功能?如果没有,我将如何实施?


当前回答

var range = (l,r) => new Array(r - l).fill().map((_,k) => k + l);

其他回答

// range()              0..10, step=1
// range(max)           0..max, step=1
// range(min,max)       min..max, step=1
// range(min,step,max)  min..max, step=step
// Use:
// console.log(...range(3));
// Array.from(range(5))
// [...range(100)]
// for (const v of range(1,10)) { ... 

function* range(...args) {
    let [min, step, max] = {
        0: [0, 1, 10],
        1: [0, args[0] >= 0 ? 1 : -1, args[0]],
        2: [args[0], args[1] >= args[0] ? 1 : -1, args[1]],
        3: args,
    }[args.length] || [];
    if (min === undefined) throw new SyntaxError("Too many arguments");
    let x = min;
    while (step >= 0 ? x < max : x > max) {
        yield x;
        x += step
    }
}
console.log(...range());      // 0 1 2 3 4 5 6 7 8 9
console.log(...range(3));     // 0 1 2
console.log(...range(2, 5));  // 2 3 4
console.log(...range(5, 2));  // 5 4 3
console.log(...range(3, -3)); // 3 2 1 0 -1 -2
console.log(...range(-3, 3)); // -3 -2 -1 0 1 2
console.log(...range(-5, -2));// -5 -4 -3
console.log(...range(-2, -5));// -2 -3 -4

为了在任何一个给定的数字可能更大的地方工作,我写了这样一个:

function getRange(start, end) {
  return Array.from({
    length: 1 + Math.abs(end - start)
  }, (_, i) => end > start ? start + i : start - i);
}

这是我模仿Python的解决方案。在底部,您可以找到一些如何使用它的示例。它与数字一起工作,就像Python的范围一样:

var assert = require('assert');    // if you use Node, otherwise remove the asserts

var L = {};    // L, i.e. 'list'

// range(start, end, step)
L.range = function (a, b, c) {
    assert(arguments.length >= 1 && arguments.length <= 3);
    if (arguments.length === 3) {
        assert(c != 0);
    }

    var li = [],
        i,
        start, end, step,
        up = true;    // Increasing or decreasing order? Default: increasing.

    if (arguments.length === 1) {
        start = 0;
        end = a;
        step = 1;
    }

    if (arguments.length === 2) {
        start = a;
        end = b;
        step = 1;
    }

    if (arguments.length === 3) {
        start = a;
        end = b;
        step = c;
        if (c < 0) {
            up = false;
        }
    }

    if (up) {
        for (i = start; i < end; i += step) {
            li.push(i);
        }
    } else {
        for (i = start; i > end; i += step) {
            li.push(i);
        }
    }

    return li;
}

示例:

// range
L.range(0) -> []
L.range(1) -> [0]
L.range(2) -> [0, 1]
L.range(5) -> [0, 1, 2, 3, 4]

L.range(1, 5) -> [1, 2, 3, 4]
L.range(6, 4) -> []
L.range(-2, 2) -> [-2, -1, 0, 1]

L.range(1, 5, 1) -> [1, 2, 3, 4]
L.range(0, 10, 2) -> [0, 2, 4, 6, 8]
L.range(10, 2, -1) -> [10, 9, 8, 7, 6, 5, 4, 3]
L.range(10, 2, -2) -> [10, 8, 6, 4]

我回顾了这里的答案,并注意到以下几点:

JavaScript没有解决此问题的内置解决方案某些答案生成大小正确但值错误的数组例如,让arr=Array.from({length:3});//给出[null,null,null]然后,使用映射函数将错误的值替换为正确的值例如arr.map((e,i)=>i);//给出[0,1,2]需要数学来移动数字范围,以满足从。。符合要求。例如arr.map((e,i)=>i+1);//给出[1,2,3]对于问题的字符串版本,需要charCodeAt和fromCharCode将字符串映射到一个数字,然后再返回到一个字符串。例如arr.map((e,i)=>String.fromCharCode(i+“A”.charCodeAt(0));//给出[“A”、“B”、“C”]

有一些基于以上部分或全部的简单到花哨的实现。当他们试图将整数和字符串解打包到一个函数中时,答案变得复杂起来。对我来说,我选择在它们自己的函数中实现整数和字符串解决方案。我证明这是合理的,因为在实践中,你会知道你的用例是什么,你会直接使用适当的函数。如果您想间接调用包装器函数,我也会提供它。

让rangeInt=(from,to)=>Array.from({length:to from+1},(e,i)=>i+from);let rangeChar=(from,to)=>数组.from({length:to.charCodeAt(0)-from.charCodeAt(0)+1},(e,i)=>字符串.fromCharCode(i+from.charCode At(1)));让范围=(从,到)=>(typeof(from)==“string”&&typeof(to)===“string”)? rangeChar(从,到):(!to)?rangeInt(0,from-1):范围Int(从,到);console.log(rangeInt(1,3));//给出[1,2,3]console.log(rangeChar(“A”,“C”));//给出[“A”、“B”、“C”]console.log(范围(1,3));//给出[1,2,3]console.log(范围(“A”、“C”));//给出[“A”、“B”、“C”]console.log(范围(3));//给出[0,1,2]

一个有趣的挑战是编写最短的函数来实现这一点。救援递归!

function r(a,b){return a>b?[]:[a].concat(r(++a,b))}

在大范围内往往速度较慢,但幸运的是量子计算机即将问世。

另一个额外的好处是,它令人困惑。因为我们都知道隐藏代码以防被窥探是多么重要。

要真正彻底混淆功能,请执行以下操作:

function r(a,b){return (a<b?[a,b].concat(r(++a,--b)):a>b?[]:[a]).sort(function(a,b){return a-b})}