Does JavaScript have a method like “range()” to generate a range within the supplied bounds?

后端 未结 30 2789
广开言路
广开言路 2020-11-22 00:51

In PHP, you can do...

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

That is, there is a function that l

相关标签:
30条回答
  • 2020-11-22 01:41

    range(start,end,step): With ES6 Iterators

    You only ask for an upper and lower bounds. Here we create one with a step too.

    You can easily create range() generator function which can function as an iterator. This means you don't have to pre-generate the entire array.

    function * range ( start, end, step = 1 ) {
      let state = start;
      while ( state < end ) {
        yield state;
        state += step;
      }
      return;
    };
    

    Now you may want to create something that pre-generates the array from the iterator and returns a list. This is useful for functions that accept an array. For this we can use Array.from()

    const generate_array = (start,end,step) =>
      Array.from( range(start,end,step) );
    

    Now you can generate a static array easily,

    const array1 = generate_array(1,10,2);
    const array1 = generate_array(1,7);
    

    But when something desires an iterator (or gives you the option to use an iterator) you can easily create one too.

    for ( const i of range(1, Number.MAX_SAFE_INTEGER, 7) ) {
      console.log(i)
    }
    

    Special Notes

    • If you use Ramda, they have their own R.range as does Lodash
    0 讨论(0)
  • 2020-11-22 01:43

    d3 also has a built-in range function. See https://github.com/mbostock/d3/wiki/Arrays#d3_range:

    d3.range([start, ]stop[, step])

    Generates an array containing an arithmetic progression, similar to the Python built-in range. This method is often used to iterate over a sequence of numeric or integer values, such as the indexes into an array. Unlike the Python version, the arguments are not required to be integers, though the results are more predictable if they are due to floating point precision. If step is omitted, it defaults to 1.

    Example:

    d3.range(10)
    // returns [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    
    0 讨论(0)
  • 2020-11-22 01:44

    you can use lodash function _.range(10) https://lodash.com/docs#range

    0 讨论(0)
  • 2020-11-22 01:47

    This may not be the best way. But if you are looking to get a range of numbers in a single line of code. For example 10 - 50

    Array(40).fill(undefined).map((n, i) => i + 10)
    

    Where 40 is (end - start) and 10 is the start. This should return [10, 11, ..., 50]

    0 讨论(0)
  • 2020-11-22 01:48

    An interesting challenge would be to write the shortest function to do this. Recursion to the rescue!

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

    Tends to be slow on large ranges, but luckily quantum computers are just around the corner.

    An added bonus is that it's obfuscatory. Because we all know how important it is to hide our code from prying eyes.

    To truly and utterly obfuscate the function, do this:

    function r(a,b){return (a<b?[a,b].concat(r(++a,--b)):a>b?[]:[a]).sort(function(a,b){return a-b})}
    
    0 讨论(0)
  • 2020-11-22 01:49

    It works for characters and numbers, going forwards or backwards with an optional step.

    var range = function(start, end, step) {
        var range = [];
        var typeofStart = typeof start;
        var typeofEnd = typeof end;
    
        if (step === 0) {
            throw TypeError("Step cannot be zero.");
        }
    
        if (typeofStart == "undefined" || typeofEnd == "undefined") {
            throw TypeError("Must pass start and end arguments.");
        } else if (typeofStart != typeofEnd) {
            throw TypeError("Start and end arguments must be of same type.");
        }
    
        typeof step == "undefined" && (step = 1);
    
        if (end < start) {
            step = -step;
        }
    
        if (typeofStart == "number") {
    
            while (step > 0 ? end >= start : end <= start) {
                range.push(start);
                start += step;
            }
    
        } else if (typeofStart == "string") {
    
            if (start.length != 1 || end.length != 1) {
                throw TypeError("Only strings with one character are supported.");
            }
    
            start = start.charCodeAt(0);
            end = end.charCodeAt(0);
    
            while (step > 0 ? end >= start : end <= start) {
                range.push(String.fromCharCode(start));
                start += step;
            }
    
        } else {
            throw TypeError("Only string and number types are supported");
        }
    
        return range;
    
    }
    

    jsFiddle.

    If augmenting native types is your thing, then assign it to Array.range.

    var range = function(start, end, step) {
        var range = [];
        var typeofStart = typeof start;
        var typeofEnd = typeof end;
    
        if (step === 0) {
            throw TypeError("Step cannot be zero.");
        }
    
        if (typeofStart == "undefined" || typeofEnd == "undefined") {
            throw TypeError("Must pass start and end arguments.");
        } else if (typeofStart != typeofEnd) {
            throw TypeError("Start and end arguments must be of same type.");
        }
    
        typeof step == "undefined" && (step = 1);
    
        if (end < start) {
            step = -step;
        }
    
        if (typeofStart == "number") {
    
            while (step > 0 ? end >= start : end <= start) {
                range.push(start);
                start += step;
            }
    
        } else if (typeofStart == "string") {
    
            if (start.length != 1 || end.length != 1) {
                throw TypeError("Only strings with one character are supported.");
            }
    
            start = start.charCodeAt(0);
            end = end.charCodeAt(0);
    
            while (step > 0 ? end >= start : end <= start) {
                range.push(String.fromCharCode(start));
                start += step;
            }
    
        } else {
            throw TypeError("Only string and number types are supported");
        }
    
        return range;
    
    }
    
    console.log(range("A", "Z", 1));
    console.log(range("Z", "A", 1));
    console.log(range("A", "Z", 3));
    
    
    console.log(range(0, 25, 1));
    
    console.log(range(0, 25, 5));
    console.log(range(20, 5, 5));

    0 讨论(0)
提交回复
热议问题