在 Javascript/jQuery 中创建两个数字(包括两个数字)之间的所有整数的数组
Create array of all integers between two numbers, inclusive, in Javascript/jQuery
假设我有以下复选框:
<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);
}
ES6 :
使用 Array.from(此处为文档(:
console.log(
Array.from({length:5},(v,k)=>k+1)
)
在 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);
我会在实际项目中使用 npm 中的range-inclusive
。它甚至支持向后的步骤,所以这很酷。
我强烈推荐下划线或低破折号库:
http://underscorejs.org/#range
(几乎完全兼容,显然 lodash 运行得更快,但下划线有更好的 doco 恕我直言(
_.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://jsfiddle.net/W3CUn/
对于反对者
性能
http://jsperf.com/for-push-while-set/2
在IE中更快,在Firefox中快3倍
只有在 AIPAD Air 上,FOR 循环才更快一些。
在Win8,OSX10.8,Ubuntu14.04,iPad,iPad,iPad Air,iPod上测试;
使用Chrome,FF,IE,Safari,Mobile Safari。
我想看看 for 循环未优化的旧 IE 浏览器的性能!
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 ]
我的五分钱:
整数的双向数组函数。
当范围 (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()
.
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。
纯 ES6 的解决方案
受到上面 m59 的回答的启发,但不依赖于fill
:
const range = (start, stop) => Array.from({ length: stop - start + 1 }, (_, i) => start + i)
因此,您可以像以下方式使用它:
range(3,5)
=> [3, 4, 5]
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"数字。此示例将向上或向下"计数",具体取决于 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;
}
}
如果你想步进十进制:数组范围(0,1,.01(您将需要截断任何浮点精度的值。否则你会返回这样的数字0.0600000000000000005 而不是 .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;
}
}
这里有 3 个函数,应该涵盖我能想到的所有内容(包括对其他一些答案中问题的修复(:rangeInt()
、range()
和 between()
。在所有情况下,都会考虑升序和降序。
例子
rangeInt()
包括端点,仅处理整数
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
between()
与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
}
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
我使用缩小.js因为它以低占用空间和易于理解的语法解决了我的所有问题。对我来说,它在一个框架中替代了jQuery,MustacheJS和Underscore/SugarJS。
当然,它并不像强调的那样受欢迎。这可能是某些人关心的问题。
Minified由Tim Jansen使用CC-0(公共领域(许可证提供。
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
你可以在 ES6 中的一行中做到这一点
const start = 5; // starting number
const end = 10; // ending number
const arr = Array.from({ length: end - start + 1 }, (_, i) => start + i);
console.log(arr); // [5, 6, 7, 8, 9, 10]
_Array = (length) => Object.keys(Array.from({length}))
//_Array = [0, 1, 2, 3, 4]
const range = (start: number, end: number) => {
for (var i = start, list = []; i <= end; list.push(i), i++);
return list;
};
希望下面的方法对某人有所帮助。这里count
变量可以用来提及数组长度。
const generateRandomArryOfNumbers = (min = 1, max = 100, count = 31) => {
return Array.from(new Array(count), () =>
Math.floor(Math.random() * (max - min + 1) + min)
);
};
打字稿版本:
function getAllNumbersBetween(start: number, end: number) {
var numbers: number[] = [];
for (var i = start; i < end; i++) {
numbers.push(i);
}
return numbers;
}
下划线求解
data = [];
_.times( highEnd, function( n ){ data.push( lowEnd ++ ) } );
<</div>
div class="answers"> 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;
}
在测试和调整了上面所有纯 js 解决方案之后,我为您提供以下解决方案,基于提供的最快算法,并与 python 系列兼容。
js版本甚至更好,因为它支持小数。
function range(start, end, step=1) {
if (typeof end === 'undefined') {
end = start, start = 0;
}
let len = Math.round((end - start) / step);
let arr = [];
while ( len-- ) {
arr[len] = start + (len * step);
}
return arr;
}
console.log(range(9, 18, 0.83));
/* [
9,
9.83,
10.66,
11.49,
12.32,
13.149999999999999,
13.98,
14.809999999999999,
15.64,
16.47,
17.299999999999997
] */
console.log(range(9, 18, 2)); // [9, 11, 13, 15, 17]
console.log(range(9, 18)); // [9, 10, 11, 12, 13, 14, 15, 16, 17]
console.log(range(9)); // [0, 1, 2, 3, 4, 5, 6, 7, 8]
请参阅 Python 代码,仅适用于整数:
print(list(range(9, 18, 2))); # [9, 11, 13, 15, 17]
print(list(range(9, 18))); # [9, 10, 11, 12, 13, 14, 15, 16, 17]
print(list(range(9))); # [0, 1, 2, 3, 4, 5, 6, 7, 8]
- 使用全局变量来存储数字(JavaScript)
- 字符串到数字JavaScript
- 查找总和最大的数字(Javascript)
- 将字符串中的重复字符替换为不断增长的数字 [Javascript]
- 选择下拉选项时显示数字-javascript
- 用户在数字上输入金额,然后输出最高数字javascript
- 字母数字 JavaScript 正则表达式失败
- 仅数字 Javascript 表单验证
- 如何从一组特定的数字中找到最接近的更高数字:javascript
- 将字符串 num 转换为数字 JavaScript
- 将字符串转换为数字 Javascript
- 提取两种模式之间的数字 javascript
- 添加两个十六进制数字 javascript 与位移
- 确定是否按下了字母或数字-Javascript
- 可以't将字符串转换为数字javascript我的代码出了什么问题
- 按布尔值,然后按数字(javascript)对对象数组进行排序
- 正则表达式,用于获取方括号之间的字符串和数字-javascript
- If和Else比较数字JavaScript
- 检查变量是网页上的所有数字javascript
- 同时检查模为0的两个不同数字(Javascript)