在Javascript / jQuery中创build包含两个数字的所有整数的数组

说我有以下checkbox:

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

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

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

那么我该如何创build一个包含lowEndhighEnd之间的所有整数的数组,包括lowEndhighEnd ? 对于这个特定的例子,显然,结果数组将是:

 [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 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++); } 

我强烈build议使用下划线或下划线库

http://underscorejs.org/#range

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

_.range([开始],停止,[步骤])

不只是为了这个,而是一堆非常有用的工具

在JavaScript ES6中:

 function range(start, end) { return Array(end - start + 1).fill().map((_, idx) => start + idx) } var result = range(9, 18); // [9, 10, 11, 12, 13, 14, 15, 16, 17, 18] console.log(result); 

最快的方式

  1. 而 – 在大多数浏览器上更快
  2. 直接设置variables比推送更快

function:

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

要么

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

编辑

可读版本

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

演示

http://jsfiddle.net/W3CUn/

为下颚

性能

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

在ie中速度更快,Firefox中速度更快3倍

只有在aipad空气的for循环有点快。

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

与铬,FF,即Safari,移动Safari。

我希望在for循环未被优化的较旧的ie浏览器上看到性能!

用例

 var genArr=(1)['..'](10) //[1,2,3,4,5,6,7,8,9,10] 

API;

 Number.prototype['..']=function(to,step){ var arr = [],from=this; while(from <= to){ arr.push(from++); } return arr; }; 

FIDDLE:

http://jsfiddle.net/abdennour/mcpnvsmm/


ES6:

 console.log( Array.from({length:10},(v,k)=>k+1) ) 
 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); 

这将创build正确的标称长度的稀疏matrix。 现在用一个稀疏matrix的问题是,尽pipe它具有正确的标称长度,但它没有实际的元素,因此

 j = 7, k = 13 console.log(a); 

给我们

 Array [ <7 empty slots> ] 

然后

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

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

所以现在,

  console.log(b); 

产量

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

最后

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

利用Array.map函数将当前元素的值和当前元素的索引传递给地图委托/callback的事实。 第一个参数被丢弃,然后第二个参数可以用来设置正确的序列值,调整后的起始偏移量。

那么

 console.log(c); 

产量

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

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

 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] 

如果我们希望能够通过第三个参数来修改用于构build数组的步骤,并且即使启动大于结束,也可以使其工作:

 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。

 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; 

可能有DRYer的方式来做循环,但这是基本的想法。

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

您可以devise一个范围方法,将“起始”数字增加一个所需的数量,直到达到“到”数字。 这个例子将“计数”向上或向下,取决于从大于还是小于。

 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; } } 

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

代码与下划线和其他代码类似:

 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

我使用minified.js,因为它解决了我的所有问题,占用空间小,语法简单易懂。 对我来说,它是一个框架中的jQuery,MustacheJS和Underscore / SugarJS的替代品。

当然,它并不是那么受欢迎的下划线。 这可能是一些关注。

Tim Jansen使用CC-0(公共领域)许可证进行了缩小。

我的五美分:

双方向整数数组函数。

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

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

根据这个答案。

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

PS为了在现实生活中使用,还应该检查isFinite()isNaN()

  function getRange(a,b) { ar = new Array(); var y = a - b > 0 ? a - b : b - a; for (i=1;i<y;i++) { ar.push(i+b); } return ar; } 

用下划线解决

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