JavaScript是否有像"range()"这样的方法来生成提供的范围内的范围?

ale*_*lex 745 javascript arrays

在PHP中,你可以做...

range(1, 3); // Array(1, 2, 3)
range("A", "C"); // Array("A", "B", "C")
Run Code Online (Sandbox Code Playgroud)

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

是否内置了JavaScript本身的内容?如果没有,我将如何实施它?

Ben*_*Ben 1242

数字

[...Array(5).keys()];
 => [0, 1, 2, 3, 4]
Run Code Online (Sandbox Code Playgroud)

字符迭代

String.fromCharCode(...[...Array('D'.charCodeAt(0) - 'A'.charCodeAt(0) + 1).keys()].map(i => i + 'A'.charCodeAt(0)));
 => "ABCD"
Run Code Online (Sandbox Code Playgroud)

迭代

for (const x of Array(5).keys()) {
  console.log(x, String.fromCharCode('A'.charCodeAt(0) + x));
}
 => 0,"A" 1,"B" 2,"C" 3,"D" 4,"E"
Run Code Online (Sandbox Code Playgroud)

作为功​​能

function range(size, startAt = 0) {
    return [...Array(size).keys()].map(i => i + startAt);
}

function characterRange(startChar, endChar) {
    return String.fromCharCode(...range(endChar.charCodeAt(0) -
            startChar.charCodeAt(0), startChar.charCodeAt(0)))
}
Run Code Online (Sandbox Code Playgroud)

作为打字功能

function range(size:number, startAt:number = 0):ReadonlyArray<number> {
    return [...Array(size).keys()].map(i => i + startAt);
}

function characterRange(startChar:string, endChar:string):ReadonlyArray<string> {
    return String.fromCharCode(...range(endChar.charCodeAt(0) -
            startChar.charCodeAt(0), startChar.charCodeAt(0)))
}
Run Code Online (Sandbox Code Playgroud)

lodash.js _.range()功能

_.range(10);
 => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
_.range(1, 11);
 => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
_.range(0, 30, 5);
 => [0, 5, 10, 15, 20, 25]
_.range(0, -10, -1);
 => [0, -1, -2, -3, -4, -5, -6, -7, -8, -9]
String.fromCharCode(..._.range('A'.charCodeAt(0), 'D'.charCodeAt(0) + 1));
 => "ABCD"
Run Code Online (Sandbox Code Playgroud)

没有库的旧非es6浏览器:

Array.apply(null, Array(5)).map(function (_, i) {return i;});
 => [0, 1, 2, 3, 4]
Run Code Online (Sandbox Code Playgroud)

console.log([...Array(5).keys()]);
Run Code Online (Sandbox Code Playgroud)

谢谢.

(ES6归功于nils petersohn和其他评论者)

  • 因为它在任何地方都很有用,它可能在JS中很有用.(JS可以做函数式编程类型的东西,它可以受益于范围(0声明.在一些半成本情况下它可能有用的其他一千个原因) (66认同)
  • Array.from(阵列(5).keys()) (58认同)
  • `Array(5).fill()`也是可映射的 (14认同)
  • @Lewis因为定义的数组有*empty*slots,不会用`map()`或其中一个朋友迭代. (10认同)
  • 任何想法为什么简单地使用`(new Array(5)).map(function(value,index){return index;})`不起作用?这会在Chrome DevTools中为我返回`[undefined×5]`. (5认同)
  • `Array.from(Array(5).keys())` 是一个 ES6 替代方案,如果有人在看的话,它可以在没有 `downlevelIteration` 编译器标志的打字稿中工作 (3认同)
  • 以防万一,如果你想以 1 开始数组,那么你可以通过将 map 函数传递给 Array from() `Array.from(Array(10), (_, i) =&gt; i + 1) / /=&gt; [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]` 来源:/sf/answers/2334682311/ (3认同)
  • 有用的Lodash功能,但没有回答这个问题的第二部分:如何创建一个字符范围. (2认同)

Cap*_*apK 297

对于数字,你可以使用ES6 Array.from(),这些日子除了IE以外的所有东西都可以使用:

更短的版本:

Array.from({length: 20}, (x,i) => i);
Run Code Online (Sandbox Code Playgroud)

更长的版本:

Array.from(new Array(20), (x,i) => i)
Run Code Online (Sandbox Code Playgroud)

它创建一个从0到19(包括0和19)的数组.这可以进一步缩短为以下形式之一:

Array.from(Array(20).keys())
// or
[...Array(20).keys()]
Run Code Online (Sandbox Code Playgroud)

也可以指定下限和上限,例如:

Array.from(new Array(20), (x,i) => i + *lowerBound*)
Run Code Online (Sandbox Code Playgroud)

一篇文章更详细地描述了这一点:http://www.2ality.com/2014/05/es6-array-methods.html

  • 第一个例子甚至可以简化为[... Array(20).keys()] (49认同)
  • 比`Array.from()`方法稍微简洁一点,并且比两者都快:`Array(20).fill().map((_,i)=> i)` (25认同)
  • @Delapouite @jib这也是:`Array.from({length:end - start},(v,k)=> k + start)` (8认同)
  • @Delapouite 太棒了!你应该把它作为一个单独的答案,我会投票给它!这也是[这个副本](http://stackoverflow.com/questions/36947847/how-to-generate-range-of-numbers-from-0-to-n-in-es2015-only)的完美答案。 (3认同)
  • @icc97 是的,linter 可能会抱怨,尽管在 JavaScript 中省略了定义为与传递“undefined”相同的函数参数,因此“fill()”(不带参数)本身并不是_错误_。该解决方案中未使用填充值,因此如果您愿意,可以使用“fill(0)”来保存一些字符。 (2认同)

Kut*_*yel 109

我最喜欢的表格(ES2015)

Array(10).fill(1).map((x, y) => x + y)
Run Code Online (Sandbox Code Playgroud)

如果你需要一个带step参数的函数:

const range = (start, stop, step = 1) =>
  Array(Math.ceil((stop - start) / step)).fill(start).map((x, y) => x + y * step)
Run Code Online (Sandbox Code Playgroud)

  • let range =(start,stop,step = 1)=>数组(停止 - 开始).fill(开始).map((x,y)=> x + y*步) (5认同)
  • @rodfersou FYI:你的例子是错的.`stop`实际上不是停止/结束位置,而是计数/距离.(没有冒犯,只是为了让人们意识到错字) (4认同)
  • 对于困惑 - 由于在Lekschas评论之后的rodfersou编辑,他的代码现在是正确的. (4认同)
  • 这是实际回答完全实现`range`方法的Javascript函数的完整问题的最佳答案.当前高于此值的所有其他(除了lodash的`_.range`)实现基本迭代器而不是具有start,stop和step的实际范围函数 (3认同)
  • 您传递给 `Array(Math.ceil((stop - start) / step) + 1)` 的参数,最后需要 `+1`,以真正模仿 php 的“包容性”行为。 (2认同)

jfl*_*net 98

这是我的2美分:

function range(start, count) {
  return Array.apply(0, Array(count))
    .map((element, index) => index + start);
}
Run Code Online (Sandbox Code Playgroud)

  • 这实际上是错误的,因为问题是要求开始和结束值.不开始和计数/距离. (5认同)
  • 这个答案没有按预期工作。输出无法使用。 (3认同)

ale*_*lex 70

它适用于字符和数字,可选步骤前进或后退.

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;

}
Run Code Online (Sandbox Code Playgroud)

jsFiddle.

如果扩展本机类型是您的事情,那么将其分配给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));
Run Code Online (Sandbox Code Playgroud)


Rem*_*emi 47

简单范围功能:

function range(start, stop, step) {
    var a = [start], b = start;
    while (b < stop) {
        a.push(b += step || 1);
    }
    return a;
}
Run Code Online (Sandbox Code Playgroud)

  • 加上UNO可用和可读.我见过很长时间的最佳代码片段. (3认同)

ken*_*bec 35

Array.range= function(a, b, step){
    var A= [];
    if(typeof a== 'number'){
        A[0]= a;
        step= step || 1;
        while(a+step<= b){
            A[A.length]= a+= step;
        }
    }
    else{
        var s= 'abcdefghijklmnopqrstuvwxyz';
        if(a=== a.toUpperCase()){
            b=b.toUpperCase();
            s= s.toUpperCase();
        }
        s= s.substring(s.indexOf(a), s.indexOf(b)+ 1);
        A= s.split('');        
    }
    return A;
}


    Array.range(0,10);
    // [0,1,2,3,4,5,6,7,8,9,10]

    Array.range(-100,100,20);
    // [-100,-80,-60,-40,-20,0,20,40,60,80,100]

    Array.range('A','F');
    // ['A','B','C','D','E','F')

    Array.range('m','r');
    // ['m','n','o','p','q','r']
Run Code Online (Sandbox Code Playgroud)

  • 你真的不应该在“Array”原型上偷工减料。 (5认同)

Ali*_*eza 35

好的,在JavaScript中我们没有range()PHP这样的函数,所以我们需要创建一个非常容易的函数,我为你编写了几个单行函数,并将它们分别用于NumbersAlphabets,如下所示:

对于数字:

function numberRange (start, end) {
  return new Array(end - start).fill().map((d, i) => i + start);
}
Run Code Online (Sandbox Code Playgroud)

并称之为:

numberRange(5, 10); //[5, 6, 7, 8, 9]
Run Code Online (Sandbox Code Playgroud)

对于字母:

function alphabetRange (start, end) {
  return new Array(end.charCodeAt(0) - start.charCodeAt(0)).fill().map((d, i) => String.fromCharCode(i + start.charCodeAt(0)));
}
Run Code Online (Sandbox Code Playgroud)

并称之为:

alphabetRange('c', 'h'); //["c", "d", "e", "f", "g"]
Run Code Online (Sandbox Code Playgroud)

  • 我认为这些功能存在一对一的错误。应该是Array(end-start + 1)和Array(end.charCodeAt(0)-start.charCodeAt(0)+ 1)。 (2认同)

nki*_*tku 27

/sf/answers/3470413201/

使用 Delta/Step

最小单线
[...Array(N)].map((_, i) => from + i * step);
Run Code Online (Sandbox Code Playgroud)

示例和其他替代方案

[...Array(10)].map((_, i) => 4 + i * 2);
//=> [4, 6, 8, 10, 12, 14, 16, 18, 20, 22]

Array.from(Array(10)).map((_, i) => 4 + i * 2);
//=> [4, 6, 8, 10, 12, 14, 16, 18, 20, 22]

Array.from(Array(10).keys()).map(i => 4 + i * 2);
//=> [4, 6, 8, 10, 12, 14, 16, 18, 20, 22]

[...Array(10).keys()].map(i => 4 + i * -2);
//=> [4, 2, 0, -2, -4, -6, -8, -10, -12, -14]

Array(10).fill(0).map((_, i) => 4 + i * 2);
//=> [4, 6, 8, 10, 12, 14, 16, 18, 20, 22]

Array(10).fill().map((_, i) => 4 + i * -2);
//=> [4, 2, 0, -2, -4, -6, -8, -10, -12, -14]
Run Code Online (Sandbox Code Playgroud) 范围函数
const range = (from, to, step) =>
  [...Array(Math.floor((to - from) / step) + 1)].map((_, i) => from + i * step);

range(0, 9, 2);
//=> [0, 2, 4, 6, 8]

// can also assign range function as static method in Array class (but not recommended )
Array.range = (from, to, step) =>
  [...Array(Math.floor((to - from) / step) + 1)].map((_, i) => from + i * step);

Array.range(2, 10, 2);
//=> [2, 4, 6, 8, 10]

Array.range(0, 10, 1);
//=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Array.range(2, 10, -1);
//=> []

Array.range(3, 0, -1);
//=> [3, 2, 1, 0]
Run Code Online (Sandbox Code Playgroud) 作为迭代器
class Range {
  constructor(total = 0, step = 1, from = 0) {
    this[Symbol.iterator] = function* () {
      for (let i = 0; i < total; yield from + i++ * step) {}
    };
  }
}

[...new Range(5)]; // Five Elements
//=> [0, 1, 2, 3, 4]
[...new Range(5, 2)]; // Five Elements With Step 2
//=> [0, 2, 4, 6, 8]
[...new Range(5, -2, 10)]; // Five Elements With Step -2 From 10
//=>[10, 8, 6, 4, 2]
[...new Range(5, -2, -10)]; // Five Elements With Step -2 From -10
//=> [-10, -12, -14, -16, -18]

// Also works with for..of loop
for (i of new Range(5, -2, 10)) console.log(i);
// 10 8 6 4 2
Run Code Online (Sandbox Code Playgroud) 仅作为发电机
const Range = function* (total = 0, step = 1, from = 0) {
  for (let i = 0; i < total; yield from + i++ * step) {}
};

Array.from(Range(5, -2, -10));
//=> [-10, -12, -14, -16, -18]

[...Range(5, -2, -10)]; // Five Elements With Step -2 From -10
//=> [-10, -12, -14, -16, -18]

// Also works with for..of loop
for (i of Range(5, -2, 10)) console.log(i);
// 10 8 6 4 2

// Lazy loaded way
const number0toInf = Range(Infinity);
number0toInf.next().value;
//=> 0
number0toInf.next().value;
//=> 1
// ...
Run Code Online (Sandbox Code Playgroud)

从到与步骤/增量

使用迭代器
class Range2 {
  constructor(to = 0, step = 1, from = 0) {
    this[Symbol.iterator] = function* () {
      let i = 0,
        length = Math.floor((to - from) / step) + 1;
      while (i < length) yield from + i++ * step;
    };
  }
}
[...new Range2(5)]; // First 5 Whole Numbers
//=> [0, 1, 2, 3, 4, 5]

[...new Range2(5, 2)]; // From 0 to 5 with step 2
//=> [0, 2, 4]

[...new Range2(5, -2, 10)]; // From 10 to 5 with step -2
//=> [10, 8, 6]
Run Code Online (Sandbox Code Playgroud) 使用发电机
const Range2 = function* (to = 0, step = 1, from = 0) {
  let i = 0,
    length = Math.floor((to - from) / step) + 1;
  while (i < length) yield from + i++ * step;
};

[...Range2(5, -2, 10)]; // From 10 to 5 with step -2
//=> [10, 8, 6]

let even4to10 = Range2(10, 2, 4);
even4to10.next().value;
//=> 4
even4to10.next().value;
//=> 6
even4to10.next().value;
//=> 8
even4to10.next().value;
//=> 10
even4to10.next().value;
//=> undefined
Run Code Online (Sandbox Code Playgroud)

对于打字稿

class _Array<T> extends Array<T> {
  static range(from: number, to: number, step: number): number[] {
    return Array.from(Array(Math.floor((to - from) / step) + 1)).map(
      (v, k) => from + k * step
    );
  }
}
_Array.range(0, 9, 1);
Run Code Online (Sandbox Code Playgroud)

/sf/answers/4521941861/

单行生成字符列表

class _Array<T> extends Array<T> {
  static range(from: number, to: number, step: number): number[] {
    return Array.from(Array(Math.floor((to - from) / step) + 1)).map(
      (v, k) => from + k * step
    );
  }
}
_Array.range(0, 9, 1);
Run Code Online (Sandbox Code Playgroud)

对于打字稿

const charList = (p: string, q: string, d = 1) => {
  const a = p.charCodeAt(0),
    z = q.charCodeAt(0);
  return [...Array(Math.floor((z - a) / d) + 1)].map((_, i) =>
    String.fromCharCode(a + i * d)
  );
};
Run Code Online (Sandbox Code Playgroud)

  • 我想说相当全面 (2认同)

alo*_*ica 26

如果在 Visual Studio Code 上遇到以下错误:

截屏

类型“IterableIterator”不是数组类型或字符串类型。使用编译器选项“--downlevelIteration”允许迭代器进行迭代。

代替

[...Array(3).keys()]
Run Code Online (Sandbox Code Playgroud)

你可以信赖

Array.from(Array(3).keys())
Run Code Online (Sandbox Code Playgroud)

更多关于downlevelIteration


aze*_*ati 23

方便的功能来完成这个技巧,运行下面的代码片段

function range(start, end, step, offset) {
  
  var len = (Math.abs(end - start) + ((offset || 0) * 2)) / (step || 1) + 1;
  var direction = start < end ? 1 : -1;
  var startingPoint = start - (direction * (offset || 0));
  var stepSize = direction * (step || 1);
  
  return Array(len).fill(0).map(function(_, index) {
    return startingPoint + (stepSize * index);
  });
  
}

console.log('range(1, 5)=> ' + range(1, 5));
console.log('range(5, 1)=> ' + range(5, 1));
console.log('range(5, 5)=> ' + range(5, 5));
console.log('range(-5, 5)=> ' + range(-5, 5));
console.log('range(-10, 5, 5)=> ' + range(-10, 5, 5));
console.log('range(1, 5, 1, 2)=> ' + range(1, 5, 1, 2));
Run Code Online (Sandbox Code Playgroud)

这是如何使用它

范围(开始,结束,步骤= 1,偏移= 0);

  • 包容性 - 前进 range(5,10) // [5, 6, 7, 8, 9, 10]
  • 包容性 - 落后 range(10,5) // [10, 9, 8, 7, 6, 5]
  • 步 - 向后 range(10,2,2) // [10, 8, 6, 4, 2]
  • 独家 - 前锋 range(5,10,0,-1) // [6, 7, 8, 9] not 5,10 themselves
  • 偏移 - 扩展 range(5,10,0,1) // [4, 5, 6, 7, 8, 9, 10, 11]
  • 抵消 - 缩小 range(5,10,0,-2) // [7, 8]
  • 步骤 - 扩大 range(10,0,2,2) // [12, 10, 8, 6, 4, 2, 0, -2]

希望你觉得它有用.


这是它的工作原理.

基本上我首先计算结果数组的长度,并为该长度创建一个零填充数组,然后用所需的值填充它

  • (step || 1)=>和其他类似的.这意味着使用的值step,并且如果它未提供使用1,而不是
  • 我们首先计算结果数组的长度, (Math.abs(end - start) + ((offset || 0) * 2)) / (step || 1) + 1)使其更简单(两个方向/步骤的差异*偏移)
  • 获得长度后,我们使用check here创建一个带有初始化值的空数组new Array(length).fill(0);
  • 现在我们有一个[0,0,0,..]我们想要的长度数组.我们映射它并使用我们需要的值返回一个新数组Array.map(function() {})
  • var direction = start < end ? 1 : 0;显然,如果start不小于end我们需要向后移动.我的意思是从0到5,反之亦然
  • 在每次迭代中,startingPoint+ stepSize*index将为我们提供所需的价值

  • 方便,当然.简单?我不敢苟同; 不管你是不是一个班轮.来自Python,这是一个震惊. (8认同)

Art*_*sun 22

var range = (l,r) => new Array(r - l).fill().map((_,k) => k + l);
Run Code Online (Sandbox Code Playgroud)

  • 这个答案需要解释,因为它不适合SO. (4认同)
  • 井井有条!虽然,重要的是要注意它不适用于任何IE或Opera. (2认同)

c.P*_*.u1 18

使用Harmony 传播操作符和箭头函数:

var range = (start, end) => [...Array(end - start + 1)].map((_, i) => start + i);
Run Code Online (Sandbox Code Playgroud)

例:

range(10, 15);
[ 10, 11, 12, 13, 14, 15 ]
Run Code Online (Sandbox Code Playgroud)


Mik*_*scu 16

标准Javascript没有内置函数来生成范围.一些javascript框架添加了对这些功能的支持,或者正如其他人指出的那样,你可以随时使用自己的功能.

如果您想仔细检查,最终资源是ECMA-262标准.

  • 好吧,这根本没有帮助。 (8认同)
  • @Pithikos 我看到这个问题已经被编辑,因为它最初被问到,OP 想知道 JS 中是否有本机范围函数。 (3认同)

Jus*_*tin 14

对一些不同的范围函数进行了一些研究. 检查jsperf比较执行这些功能的不同方法.当然不是一个完美或详尽的清单,但应该帮助:)

获胜者是......

function range(lowEnd,highEnd){
    var arr = [],
    c = highEnd - lowEnd + 1;
    while ( c-- ) {
        arr[c] = highEnd--
    }
    return arr;
}
range(0,31);
Run Code Online (Sandbox Code Playgroud)

从技术上讲,它不是firefox上最快的,但是Chrome上的疯狂速度差异(imho)弥补了它.

同样有趣的观察是这些数组函数的速度比firefox快多少.Chrome的速度至少快4到5倍.


Pao*_*tti 13

你可以使用lodashUndescore.js range:

var range = require('lodash/range')
range(10)
// -> [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
Run Code Online (Sandbox Code Playgroud)

或者,如果您只需要一个连续的整数范围,您可以执行以下操作:

Array.apply(undefined, { length: 10 }).map(Number.call, Number)
// -> [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
Run Code Online (Sandbox Code Playgroud)

在ES6中range可以使用生成器实现:

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;
  }
}
Run Code Online (Sandbox Code Playgroud)

这种实现在迭代大型序列时可以节省内存,因为它不必将所有值都实现为数组:

for (let i of range(1, oneZillion)) {
  console.log(i);
}
Run Code Online (Sandbox Code Playgroud)


LKB*_*LKB 13

(from, to) => [...Array(to - from)].map((_,i)=> i + from)
Run Code Online (Sandbox Code Playgroud)


DIN*_*LIT 13

如果只想使用范围来重复过程 n 次,您可以简单地使用此代码

[...Array(10)].map((item, index) => ( 
    console.log("item:", index)
))
Run Code Online (Sandbox Code Playgroud)


Her*_* Qu 12

使用ES6发生器的另一个版本(参见伟大的Paolo Moretti回答ES6发生器):

const RANGE = (a,b) => Array.from((function*(x,y){
  while (x <= y) yield x++;
})(a,b));

console.log(RANGE(3,7));  // [ 3, 4, 5, 6, 7 ]
Run Code Online (Sandbox Code Playgroud)

或者,如果我们只需要迭代,那么:

const RANGE_ITER = (a,b) => (function*(x,y){
  while (x <= y) yield x++;
})(a,b);

for (let n of RANGE_ITER(3,7)){
  console.log(n);
}

// 3
// 4
// 5
// 6
// 7
Run Code Online (Sandbox Code Playgroud)

  • 只是 ```const range = (x, y) =&gt; Array.from(function* () { while (x &lt;= y) yield x++; }())``` (2认同)

小智 12

我个人最喜欢的:

const range = (start, end) => new Array(end-start+1).fill().map((el, ind) => ind + start);
Run Code Online (Sandbox Code Playgroud)


Ric*_*ock 10

一个有趣的挑战是编写最短的函数来做到这一点.救援的递归!

function r(a,b){return a>b?[]:[a].concat(r(++a,b))}
Run Code Online (Sandbox Code Playgroud)

在大范围内趋于缓慢,但幸运的是量子计算机即将到来.

一个额外的好处是它是混淆的.因为我们都知道将我们的代码隐藏起来是多么重要.

要真正彻底地混淆函数,请执行以下操作:

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

  • 简短!=简单,但更简单更好.这是一个更容易阅读的版本:`const range =(a,b)=>(a> = b)?[]:[a,... range(a + 1,b)]`,使用ES6语法 (4认同)

Sas*_*sky 9

我会编码这样的代码:

function range(start, end) {
    return Array(end-start).join(0).split(0).map(function(val, id) {return id+start});
}  

range(-4,2);
// [-4,-3,-2,-1,0,1]

range(3,9);
// [3,4,5,6,7,8]
Run Code Online (Sandbox Code Playgroud)

它的行为类似于Python范围:

>>> range(-4,2)
[-4, -3, -2, -1, 0, 1]
Run Code Online (Sandbox Code Playgroud)


Roc*_*ini 9

这个也可以反向工作。

const range = ( a , b ) => Array.from( new Array( b > a ? b - a : a - b ), ( x, i ) => b > a ? i + a : a - i );

range( -3, 2 ); // [ -3, -2, -1, 0, 1 ]
range( 1, -4 ); // [ 1, 0, -1, -2, -3 ]
Run Code Online (Sandbox Code Playgroud)


Ise*_*chO 8

可以如下创建大量使用ES6的相当简约的实现,特别注意Array.from()静态方法:

const getRange = (start, stop) => Array.from(
  new Array((stop - start) + 1),
  (_, i) => i + start
);
Run Code Online (Sandbox Code Playgroud)


Ric*_*all 8

尚未实施!

使用新Number.range 提案(阶段 1):

[...Number.range(1, 10)]
//=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Run Code Online (Sandbox Code Playgroud)


小智 7

虽然这不是来自PHP,而是range来自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] 
Run Code Online (Sandbox Code Playgroud)


Eva*_*oll 7

range(start,end,step):使用ES6迭代器

您只要求一个上限和下限。在这里,我们也创建了一个步骤。

您可以轻松地创建range()可用作迭代器的生成器函数。这意味着您不必预先生成整个数组。

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

现在,您可能需要创建一些东西,以便从迭代器中预生成数组并返回一个列表。这对于接受数组的函数很有用。为此,我们可以使用Array.from()

const generate_array = (start,end,step) =>
  Array.from( range(start,end,step) );
Run Code Online (Sandbox Code Playgroud)

现在,您可以轻松生成静态数组,

const array1 = generate_array(1,10,2);
const array1 = generate_array(1,7);
Run Code Online (Sandbox Code Playgroud)

但是,当某些东西需要迭代器(或为您提供使用迭代器的选项)时,您也可以轻松创建一个迭代器。

for ( const i of range(1, Number.MAX_SAFE_INTEGER, 7) ) {
  console.log(i)
}
Run Code Online (Sandbox Code Playgroud)

特别说明


Rah*_*ala 7

您可以使用以下单行代码来使事情简短而简单

var start = 4;
var end = 20;
console.log(Array(end - start + 1).fill(start).map((x, y) => x + y));
Run Code Online (Sandbox Code Playgroud)


Don*_*nga 7

用这个。它创建一个具有给定数量值(未定义)的数组,在下面的示例中有 100 个索引,但它不相关,因为在这里您只需要键。它在数组中使用 100 + 1,因为数组总是基于 0 索引。因此,如果要生成 100 个值,则索引从 0 开始;因此最后一个值总是 99 而不是 100。

range(2, 100);

function range(start, end) {
    console.log([...Array(end + 1).keys()].filter(value => end >= value && start <= value ));
}
Run Code Online (Sandbox Code Playgroud)


Jan*_*sen 6

使用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;
        }
    }
});
Run Code Online (Sandbox Code Playgroud)

例子

采取

例1.

take 只需要尽可能多的钱

take(10, range( {from: 100, step: 5, to: 120} ) )

回报

[100, 105, 110, 115, 120]

例2.

to 不是必要的

take(10, range( {from: 100, step: 5} ) )

回报

[100, 105, 110, 115, 120, 125, 130, 135, 140, 145]

takeAll

例3.

from 不是必要的

takeAll( range( {to: 5} ) )

回报

[0, 1, 2, 3, 4, 5]

例4.

takeAll( range( {to: 500, step: 100} ) )

回报

[0, 100, 200, 300, 400, 500]

例5.

takeAll( range( {from: 'z', to: '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"]


jha*_*ell 6

至于为给定范围生成数值数组,我使用:

function range(start, stop)
{
    var array = [];

    var length = stop - start; 

    for (var i = 0; i <= length; i++) { 
        array[i] = start;
        start++;
    }

    return array;
}

console.log(range(1, 7));  // [1,2,3,4,5,6,7]
console.log(range(5, 10)); // [5,6,7,8,9,10]
console.log(range(-2, 3)); // [-2,-1,0,1,2,3]
Run Code Online (Sandbox Code Playgroud)

显然,它不适用于字母数组.


Bob*_*ley 6

d3 还有一个内置的 range 函数。见https://github.com/mbostock/d3/wiki/Arrays#d3_range

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

生成一个包含等差数列的数组,类似于 Python 内置范围。此方法通常用于迭代一系列数字或整数值,例如数组中的索引。与 Python 版本不同,参数不需要是整数,但如果由于浮点精度,结果更可预测。如果省略 step,则默认为 1。

例子:

d3.range(10)
// returns [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Run Code Online (Sandbox Code Playgroud)


Mar*_*man 6

我的 codegolfing 同事想出了这个(ES6),包括:

(s,f)=>[...Array(f-s+1)].map((e,i)=>i+s)
Run Code Online (Sandbox Code Playgroud)

不包括:

(s,f)=>[...Array(f-s)].map((e,i)=>i+s)
Run Code Online (Sandbox Code Playgroud)


Edi*_*uza 6

这可能不是最好的方法。但是,如果您希望在一行代码中获得一系列数字。例如10-50

Array(40).fill(undefined).map((n, i) => i + 10)
Run Code Online (Sandbox Code Playgroud)

其中40是(结束-开始),而10是开始。这应该返回[10,11,...,50]


小智 5

你可以使用https://lodash.com/docs#rangelodash函数_.range(10)


Ano*_*112 5

使用 range([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)
}
Run Code Online (Sandbox Code Playgroud)

如果您想要自动负步进,请添加

if(stop<start)step=-Math.abs(step)
Run Code Online (Sandbox Code Playgroud)

或者更简约:

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)
}
Run Code Online (Sandbox Code Playgroud)

如果您的范围很大,请查看 Paolo Moretti 的生成器方法


小智 5

...更多范围,使用发电机功能.

function range(s, e, str){
  // create generator that handles numbers & strings.
  function *gen(s, e, str){
    while(s <= e){
      yield (!str) ? s : str[s]
      s++
    }
  }
  if (typeof s === 'string' && !str)
    str = 'abcdefghijklmnopqrstuvwxyz'
  const from = (!str) ? s : str.indexOf(s)
  const to = (!str) ? e : str.indexOf(e)
  // use the generator and return.
  return [...gen(from, to, str)]
}

// usage ...
console.log(range('l', 'w'))
//=> [ 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w' ]

console.log(range(7, 12))
//=> [ 7, 8, 9, 10, 11, 12 ]

// first 'o' to first 't' of passed in string.
console.log(range('o', 't', "ssshhhooooouuut!!!!"))
// => [ 'o', 'o', 'o', 'o', 'o', 'u', 'u', 'u', 't' ]

// only lowercase args allowed here, but ...
console.log(range('m', 'v').map(v=>v.toUpperCase()))
//=> [ 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V' ]

// => and decreasing range ...
console.log(range('m', 'v').map(v=>v.toUpperCase()).reverse())

// => ... and with a step
console.log(range('m', 'v')
          .map(v=>v.toUpperCase())
          .reverse()
          .reduce((acc, c, i) => (i % 2) ? acc.concat(c) : acc, []))

// ... etc, etc.
Run Code Online (Sandbox Code Playgroud)

希望这很有用.


小智 5

ES6

使用 Array.from(此处为文档):

const range = (start, stop, step) => Array.from({ length: (stop - start) / step + 1}, (_, i) => start + (i * step));
Run Code Online (Sandbox Code Playgroud)


Zoh*_*rut 5

您还可以使用生成器来生成序列。\n不同之处在于序列中的每个值都是延迟加载的。扩展运算符和 for of 计算结果。\n星号使该函数成为生成器。

\n
const range = function*(from,to) { \xc2\xa0 \n    for(let i = from; i <= to; i++) yield I; \xc2\xa0 \n}; \xc2\xa0 \n\n[...range(3,5)]// => [3, 4, 5]\n
Run Code Online (Sandbox Code Playgroud)\n


spp*_*c42 5

Op 要求一个范围,比如range(3, 10),所以它可以是

[...[...Array(10-3).keys()].map(i => i+3)]
Run Code Online (Sandbox Code Playgroud)

回报

[3, 4, 5, 6, 7, 8, 9]
Run Code Online (Sandbox Code Playgroud)