假设我有以下复选框:

<input type="checkbox" value="1-25" />

为了得到定义我正在寻找的范围边界的两个数字,我使用下面的jQuery:

var value = $(this).val();
var lowEnd = Number(value.split('-')[0]);
var highEnd = Number(value.split('-')[1]);

然后,我如何创建一个包含lowEnd和highEnd之间的所有整数的数组,包括lowEnd和highEnd本身?对于这个特定的例子,显然,结果数组将是:

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25]

var values = $(this).val().split('-'),
    i = +values[0],
    l = +values[1],
    range = [];

while (i < l) {
    range[range.length] = i;
    i += 1;
}

range[range.length] = l;

可能有一个烘干机的方式来做循环,但这是基本的想法。


function createNumberArray(lowEnd, highEnd) {
    var start = lowEnd;
    var array = [start];
    while (start < highEnd) {
        array.push(start);
        start++;
    }
} 

var list = [];
for (var i = lowEnd; i <= highEnd; i++) {
    list.push(i);
}

我的循环版本;)

var lowEnd = 1;
var highEnd = 25;
var arr = [];
while(lowEnd <= highEnd){
   arr.push(lowEnd++);
}

您可以设计一个range方法,使“从”数增加所需的数量,直到达到“到”数。 这个例子将“计数”向上或向下,这取决于from比to大还是比to小。

Array.range= function(from, to, step){
    if(typeof from== 'number'){
        var A= [from];
        step= typeof step== 'number'? Math.abs(step):1;
        if(from> to){
            while((from -= step)>= to) A.push(from);
        }
        else{
            while((from += step)<= to) A.push(from);
        }
        return A;
    }   
}

如果你想步进一个小数:Array.range(0,1,01) 您将需要截断任何浮点不精确的值。 否则你会返回类似的数字 0.060000000000000005而不是。06。

这给另一个版本增加了一点开销,但对于整数或十进制步骤是正确的。

Array.range= function(from, to, step, prec){
    if(typeof from== 'number'){
        var A= [from];
        step= typeof step== 'number'? Math.abs(step):1;
        if(!prec){
            prec= (from+step)%1? String((from+step)%1).length+1:0;
        }
        if(from> to){
            while(+(from -= step).toFixed(prec)>= to) A.push(+from.toFixed(prec));
        }
        else{
            while(+(from += step).toFixed(prec)<= to) A.push(+from.toFixed(prec));
        }
        return A;
    }   
}

最快的方式

而——在大多数浏览器上更快 直接设置变量比推设置快

功能:

var x=function(a,b,c,d){d=[];c=b-a+1;while(c--){d[c]=b--}return d},

theArray=x(lowEnd,highEnd);

or

var arr=[],c=highEnd-lowEnd+1;
while(c--){arr[c]=highEnd--}

编辑

可读版本

var arr = [],
c = highEnd - lowEnd + 1;
while ( c-- ) {
 arr[c] = highEnd--
}

Demo

http://jsfiddle.net/W3CUn/

对于持悲观态度的选民

性能

http://jsperf.com/for-push-while-set/2

ie更快,firefox快3倍

只有在aipad air上,for循环速度略快。

在win8, osx10.8, ubuntu14.04, ipad, ipad air, ipod上测试;

chrome,ff,即,safari,移动safari。

我希望看到旧ie浏览器的性能,其中for循环没有优化!


我强烈推荐下划线或低破折号库:

http://underscorejs.org/#range

(几乎完全兼容,显然lodash运行更快,但下划线有更好的doco恕我直言)

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

这两个库都有很多非常有用的实用程序。


在下划线中求解

data = [];
_.times( highEnd, function( n ){ data.push( lowEnd ++ ) } );

如果开始总是小于结束,我们可以这样做:

function range(start, end) {
  var myArray = [];
  for (var i = start; i <= end; i += 1) {
    myArray.push(i);
  }
  return myArray;
};
console.log(range(4, 12));                 // → [4, 5, 6, 7, 8, 9, 10, 11, 12]

如果我们希望能够使用第三个参数来修改用于构建数组的步骤,并且即使开始值大于结束值也能使其工作:

function otherRange(start, end, step) {
  otherArray = [];
  if (step == undefined) {
    step = 1;
  };
  if (step > 0) {
    for (var i = start; i <= end; i += step) {
      otherArray.push(i);
    }
  } else {
    for (var i = start; i >= end; i += step) {
      otherArray.push(i);
    }
  };
  return otherArray;
};
console.log(otherRange(10, 0, -2));        // → [10, 8, 6, 4, 2, 0]
console.log(otherRange(10, 15));           // → [10, 11, 12, 13, 14, 15]
console.log(otherRange(10, 20, 2));        // → [10, 12, 14, 16, 18, 20]

这样,函数接受正步长和负步长,如果没有给出步长,则默认为1。


ES6:

使用Array.from (docs here):

console.log ( Array.from({长度:5},(v, k) = > k + 1) )


函数getRange (a, b) { ar = new Array(); Var y = a - b > 0 ?A - b: b - A; (我= 1,< y;我+ +) { ar.push (i + b); } 返回基于“增大化现实”技术; }


将http://minifiedjs.com/添加到答案列表中:)

Code类似于下划线和其他:

var l123 = _.range(1, 4);      // same as _(1, 2, 3)
var l0123 = _.range(3);        // same as _(0, 1, 2)
var neg123 = _.range(-3, 0);   // same as _(-3, -2, -1)
var empty = _.range(2,1);      // same as _()

文档: http://minifiedjs.com/api/range.html

我使用minify .js,因为它解决了我所有的问题,占用空间小,语法容易理解。对我来说,它是一个框架中jQuery, MustacheJS和下划线/SugarJS的替代品。

当然,它不像下划线那样流行。这可能是一些人的担忧。

Minified是由Tim Jansen使用CC-0(公共域)许可证提供的。


function range(j, k) { 
    return Array
        .apply(null, Array((k - j) + 1))
        .map(function(_, n){ return n + j; }); 
}

这大致相当于

function range(j, k) { 
    var targetLength = (k - j) + 1;
    var a = Array(targetLength);
    var b = Array.apply(null, a);
    var c = b.map(function(_, n){ return n + j; });
    return c;
}

分解一下:

var targetLength = (k - j) + 1;

var a = Array(targetLength);

这将创建一个具有正确标称长度的稀疏矩阵。现在,稀疏矩阵的问题是尽管它有正确的标称长度,但它没有实际的元素,所以,对于

j = 7, k = 13

console.log(a);

给了我们

Array [ <7 empty slots> ]

Then

var b = Array.apply(null, a);

将稀疏矩阵作为参数列表传递给Array构造函数,该构造函数生成一个(实际)长度为targetLength的密集矩阵,其中所有元素都具有未定义的值。第一个参数是数组构造函数执行上下文的“this”值,在这里没有作用,因此为null。

现在,

 console.log(b);

收益率

 Array [ undefined, undefined, undefined, undefined, undefined, undefined, undefined ]

最后

var c = b.map(function(_, n){ return n + j; });

利用了数组。映射函数通过:当前元素的值和2。当前元素的索引,映射委托/回调。第一个参数将被丢弃,而第二个参数在调整开始偏移量后可用于设置正确的序列值。

然后

console.log(c);

收益率

 Array [ 7, 8, 9, 10, 11, 12, 13 ]

我的五分钱:

两个方向的整数数组函数。

当range(0,5)变为[0,1,2,3,4,5]时。

范围(5,0)变为[5,4,3,2,1,0]。

基于这个答案。

function range(start, end) {
  const isReverse = (start > end);
  const targetLength = isReverse ? (start - end) + 1 : (end - start ) + 1;
  const arr = new Array(targetLength);
  const b = Array.apply(null, arr);
  const result = b.map((discard, n) => {
    return (isReverse) ? n + end : n + start;
  });

  return (isReverse) ? result.reverse() : result;
}

附注:为了在现实生活中使用,你还应该检查isFinite()和isNaN()的参数。


在JavaScript ES6中:

函数范围(start, end) { 返回Array(end - start + 1).fill()。Map ((_, idx) => start + idx) } Var结果= range(9,18);// [9,10,11,12,13,14,15,16,17,18] console.log(结果);

为了完整起见,这里有一个可选的step参数。

函数范围(start, end, step = 1) { const len =数学。楼层((结束-开始)/台阶)+ 1 返回数组(len) .fill()。Map ((_, idx) => start + (idx * step)) } Var结果= range(9,18,0.83); console.log(结果);

我会在实际项目中使用npm的range-inclusive。它甚至支持后退,这很酷。


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

来源:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from


_Array = (length) => Object.keys(Array.from({length}))

//_Array = [0, 1, 2, 3, 4]

纯ES6解决方案

受到上面m59的答案的启发,但没有对填充的依赖:

const range = (start, stop) => Array.from({ length: stop - start + 1 }, (_, i) => start + i)

你可以这样使用它:

range(3,5)
=> [3, 4, 5]

Const范围=(开始:数字,结束:数字)=> { (var I = start, list = [];I <= end;list.push(我),我+ +); 返回列表; };


希望下面的方法对大家有所帮助。 这里可以用count变量来表示数组的长度。

const generateRandomArryOfNumbers = (min = 1, max = 100, count = 31) => {
  return Array.from(new Array(count), () =>
    Math.floor(Math.random() * (max - min + 1) + min)
  );
};

这里有3个函数,它们应该涵盖了我能想到的一切(包括对其他一些答案中的问题的修复):rangeInt(), range()和between()。在所有情况下都考虑升序和降序。

例子

范围英特()

包括端点并且只处理整数

rangeInt(1, 4)  // [1, 2, 3, 4] Ascending order
rangeInt(5, 2)  // [5, 4, 3, 2] Descending order
rangeInt(4, 4)  // [4]          Singleton set (i.e. not [4, 4])
rangeInt(-1, 1) // [-1, 0, 1]   Mixing positive and negative

range ()

与rangeInt()相同,除了

不限于整数 允许在第三个参数中指定数量的点

range(0, 10, 2)  // [0, 3.333, 6.666, 10] Gets endpoints and 2 points between
range(0, 1.5, 1) // [0, 0.75, 1.5]        Accepts fractions

间()

与range()相同,除了

不包括端点 没有单例集(将返回一个空数组)

between(0, 10, 2) // [3.333, 6.666]
between(-1, -1.5) // [-1.25]
between(4, 4, 99) // []

/**
 * Gets a set of integers that are evenly distributed along a closed interval
 * @param {int} begin - Beginning endpoint (inclusive)
 * @param {int} end   - Ending endpoint (inclusive)
 * @return {Array} Range of integers
 */
function rangeInt( begin, end )  {
    if ( !Number.isInteger(begin) || !Number.isInteger(end) ) {
        throw new Error('All arguments must be integers')
    }
    return range(begin, end, Math.abs(end - begin) - 1)
}

/**
 * Gets a set of numbers that are evenly distributed along a closed interval
 * @param {Number} begin  - Beginning endpoint (inclusive)
 * @param {Number} end    - Ending endpoint (inclusive)
 * @param {int}    points - How many numbers to retrieve from the open interval
 * @return {Array} Range of numbers
 */
function range( begin, end, points ) {
    if ( begin !== end ) {
        return [ begin, ...between(begin, end, points), end ]
    }
    else if ( Number.isFinite(begin) ) {
        return [ begin ] // singleton set
    }
    else throw new Error('Endpoints must be finite')
}

/**
 * Gets a subset of numbers that are evenly distributed along an open interval
 * @param {Number} begin  - Beginning endpoint (exclusive)
 * @param {Number} end    - Ending endpoint (exclusive)
 * @param {int}    points - How many numbers to retrieve from the interval
 * @return {Array} Retrieved numbers
 */
function between( begin, end, points = 1 ) {
    if ( !Number.isFinite(begin) || !Number.isFinite(end) || !Number.isFinite(points) ) {
        throw new Error('All arguments must be finite')
    }
    const set = []
    // Skip if an open interval does not exist
    if ( begin !== end ) {
        const step = (end - begin) / (points + 1)
        for ( let i = 0; i < points; i++ ) {
            set[i] = begin + (i + 1) * step
        }
    }
    return set
}