Ответ 1
var list = [];
for (var i = lowEnd; i <= highEnd; i++) {
list.push(i);
}
Скажем, у меня есть следующий флажок:
<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);
}
Моя версия цикла;)
var lowEnd = 1;
var highEnd = 25;
var arr = [];
while(lowEnd <= highEnd){
arr.push(lowEnd++);
}
Я настоятельно рекомендую библиотеки подчеркивания или lo-dash
http://underscorejs.org/#range
(видимо, почти полностью совместимый, lodash работает быстрее, видимо, но подчеркивание лучше doco (IMHO)
_. range ([start], stop, [step])
Не только для этого, но и для очень полезных утилит
В 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);
быстрый способ
функция:
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--}
EDIT
читаемая версия
var arr = [],
c = highEnd - lowEnd + 1;
while ( c-- ) {
arr[c] = highEnd--
}
Demo
ДЛЯ ЗАГРУЗИТЕЛЕЙ
производительности
http://jsperf.com/for-push-while-set/2
быстрее в ie и 3 раза быстрее в firefox
только на айпад-воздухе цикл for работает немного быстрее.
проверено на win8, osx10.8, ubuntu14.04, ipad, ipad air, ipod;
с хром, ff, т.е. сафари, мобильное сафари.
Мне бы хотелось увидеть производительность в старых браузерах, где цикл for не оптимизирован!
var genArr=(1)['..'](10) //[1,2,3,4,5,6,7,8,9,10]
Number.prototype['..']=function(to,step){
var arr = [],from=this;
while(from <= to){
arr.push(from++);
}
return arr;
};
http://jsfiddle.net/abdennour/mcpnvsmm/
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);
это создает разреженную матрицу с правильной номинальной длиной. Теперь проблема с разреженной матрицей состоит в том, что, хотя она имеет правильную номинальную длину, она не имеет реальных элементов, поэтому для
j = 7, k = 13
console.log(a);
дает нам
Array [ <7 empty slots> ]
Тогда
var b = Array.apply(null, a);
передает разреженную матрицу в виде списка аргументов в конструктор Array, который создает плотную матрицу (фактическую) length targetLength, где все элементы имеют значение undefined. Первый аргумент - это значение '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 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.
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++;
}
}
Вы можете создать метод диапазона, который увеличивает число "от" на нужную величину до достижения номера "до". Этот пример будет "считать" вверх или вниз, в зависимости от того, больше или меньше от него.
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 в одной структуре.
Конечно, это не так популярно, как подчеркивание. Это может быть проблемой для некоторых.
Minified был предоставлен Тимом Янсеном с использованием лицензии CC-0 (public domain).
Мои пять центов:
Целый массив целых чисел.
Когда диапазон (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;
}
P.S. Для использования в реальной жизни вы также должны проверить args на 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;
}
Решение underscore
data = [];
_.times( highEnd, function( n ){ data.push( lowEnd ++ ) } );