说我有以下复选框:
<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 list = [];
for (var i = lowEnd; i <= highEnd; i++) {
list.push(i);
}
在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);
为了完整起见,此处带有可选step
参数。
function range(start, end, step = 1) {
const len = Math.floor((end - start) / step) + 1
return Array(len).fill().map((_, idx) => start + (idx * step))
}
var result = range(9, 18, 0.83);
console.log(result);
我会用range-inclusive
从NPM在实际的项目。它甚至支持后退步骤,所以很酷。
ES6:
使用Array.from(此处的文档):
console.log(
Array.from({length:5},(v,k)=>k+1)
)
我强烈建议使用下划线或破折号库:
http://underscorejs.org/#range
(几乎完全兼容,显然lodash运行更快,但下划线具有更好的doco IMHO)
_.range([start], stop, [step])
这两个库都有许多非常有用的实用程序。
我的循环版本;)
var lowEnd = 1;
var highEnd = 25;
var arr = [];
while(lowEnd <= highEnd){
arr.push(lowEnd++);
}
最快的方法
- 而-在大多数浏览器中更快
- 直接设置变量比推送更快
功能:
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://jsperf.com/for-push-while-set/2
在IE中更快,在Firefox中快3倍
仅在aipad air上,for循环要快一点。
在win8,osx10.8,ubuntu14.04,ipad,ipad air,ipod上测试;
与chrome,ff,ie,safari,mobile safari。
我想在较旧的浏览器(例如for循环未得到最佳优化的浏览器)上看到性能!
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> ]
然后
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; });
利用Array.map函数传递的事实:1.当前元素的值和2.当前元素的索引传递给映射委托/回调。调整起始偏移量后,第一个参数将被丢弃,而第二个参数可用于设置正确的序列值。
所以呢
console.log(c);
产量
Array [ 7, 8, 9, 10, 11, 12, 13 ]
function createNumberArray(lowEnd, highEnd) {
var start = lowEnd;
var array = [start];
while (start < highEnd) {
array.push(start);
start++;
}
}
如果开始总是小于结束,则可以执行以下操作:
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。
我的五分钱:
双向双向整数函数。
当range(0,5)变为时[0, 1, 2, 3, 4, 5]
。
并且range(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;
}
PS在现实生活中,您还应该检查isFinite()
和的参数isNaN()
。
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方式进行循环,但这是基本思想。
您可以设计一个范围方法,将“从”数字递增所需的数量,直到达到“到”数字。本示例将根据from是大于还是小于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;
}
}
将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(公共领域)许可证提供了Minified。
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 ++ ) } );
文章标签:arrays , javascript , jquery
版权声明:本文为原创文章,版权归 javascript 所有,欢迎分享本文,转载请保留出处!
评论已关闭!