Tersest способ создания массива целых чисел от 1..20 в JavaScript
Каким будет следующий способ создания этого массива:
var x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
11, 12, 13, 14, 15, 16, 17, 18, 19, 20];
Например, цикл for
:
var x = [];
for (var i=1;i<=20;i++) {
x.push(i);
}
Или цикл while
:
var x = [], i = 1, endInt = 20;
while (i <= endInt) {
x.push(i);
i++;
}
Были бы и другие примеры, которые были бы термисорами - другими словами - меньше кода? Я думаю о таких вещах, как Ruby, где эквивалентный код, который я считаю, будет таким же простым, как 1..20
. Я не знаю такого синтаксиса, как в JavaScript, но мне интересно, есть ли более короткие способы сделать то же самое.
ОБНОВЛЕНИЕ: Я не думал об удалении точек с запятой или var
для ответов в вопросе, но я должен признать, что вопрос подразумевает это. Мне больше любопытно об алгоритмах, чем о бритвенных байтах. Извините, если я не понял! Кроме того, превращение его в функцию достаточно просто, просто нажмите function range(start, end) { /* guts here */ }
вокруг него, и вы там. Вопрос в том, есть ли новые подходы к "кишкам".
Ответы
Ответ 1
Немного подумав об этом, это кратчайшая реализация стандартной функции range(N)
в JavaScript, которую я мог бы придумать:
function range1(i){return i?range1(i-1).concat(i):[]}
Примечание. Не используйте это в процессе производства; это O (N ^ 2)
Контраст с текущим голосом:
function range1(i){var x=[];var i=1;while(x.push(i++)<i){};return x}
Пример:
> range1(5)
[1, 2, 3, 4, 5]
Это похоже на ребёнка-плаката для рекурсии, хотя я ожидал, что он будет длиннее, пока я не подумаю о тройном-if-statement, который сводит его до 42 необходимых символов.
Обратите внимание, что "стандартная" функция range
, возвращающая [начало, конец), может быть записана с помощью .concat(i-1)
.
Обновление: Ох, я обнаружил невероятно короткую версию с уродливым императивным синтаксисом, злоупотребляя для циклов, обратного упорядочения, тот факт, что присваивания возвращают значение: for(y=[],i=20;y[--i]=i;){}
, состоящее всего из 25 символов (хотя вы захотите var y
который вы можете вставить в цикл for, а +1, если вы не хотите 0... 19). Хотя это не короче, если вам нужно определить функцию, она короче i?r(i-1).concat(i):[]
, если вам не нужно делать функцию.
Любимый метод
Обновление Sep13,2015:
Просто появился этот новый метод, который работает с браузерами, поддерживающими стандарт ES6:
> Array(5).fill().map((x,i)=>i)
[0, 1, 2, 3, 4]
Также это:
> Array.from(Array(5),(x,i)=>i)
[0, 1, 2, 3, 4]
Добавлены некоторые тестовые примеры профилирования производительности: кажется, что все, кроме стандартного in-order for-loop, на 10 раз медленнее, по крайней мере, на V8. https://jsperf.com/array-range-in-javascript
(Конечно, ничто из этого не имеет значения, если вы все-таки программируете в функциональном стиле и все равно ударяете каждый элемент с вызовом функции.)
Ответ 2
Вы можете сделать это с помощью цикла while, где нажатие происходит внутри условия .Array.push возвращает длину массива, которая в этом случае оказывается такой же, как и значение. Итак, вы можете сделать следующее:
x = []; //normally would use var here
i = 1; //normally would use var here
while(x.push(i++)<20){}
//at this point, x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
Сжатая версия (31 символ)
x=[];i=1;while(x.push(i++)<20);
Пример jsFiddle
Ответ 3
Это можно сделать с помощью функций из ES6, в настоящее время поддерживаемых только Firefox. Здесь я нашел таблицу совместимости: http://kangax.github.io/compat-table/es6/
Array.from(new Array(20), (x,i) => i+1)
Если вы хотите иметь другой диапазон, я думаю, вы могли бы сделать
Array.from(new Array(5), (x,i) => i+5)
Что было бы тогда [5,6,7,8,9]
Ответ 4
while - путь
var a=[],b=10;while(b--)a[b]=b+1
возвращает [1,2,3,4,5,6,7,8,9,10]
объясняется с началом и длиной
var array=[],length=20,start=5;while(length--)array[length]=length+start
возвращает [5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24]
хотите диапазон?
объясняется с начала и конца
var array=[],end=30,start=25,a=end-start+1;while(a--)array[a]=end--
возвращает [25, 26, 27, 28, 29, 30]
для -
for(var a=[],b=20;b>0;b--,a[b]=b+1)
для ++
for(var a=[],b=0;b<20;b++,a[b]=b+1)
ПОЧЕМУ это все равно?
1.while - это самый быстрый цикл;
настройка 2.direct быстрее, чем push и concat;
3. [] также быстрее, чем новый массив (10);
4. не намного длиннее кода, чем все остальные
методы экономии байтов
1. Использовать аргументы в качестве placholder для переменных функции
2. Не используйте новые Array(), push(), concat(), если не нужно
3.place "() {};," только при необходимости.
4.use a, b, c, d... в коротких функциях.
поэтому, если u хочет функцию для этого
с началом, концом (диапазон)
function range(a,b,c,d){d=[];c=b-a+1;while(c--)d[c]=b--;return d}
так что теперь диапазон (3,7) возвращает [3,4,5,6,7]
u сохраните байты во многих отношениях здесь, и эта функция также очень быстро, так как она не использует concat, push, new Array и делает это некоторое время -
Ответ 5
Использование ES6
numArr = Array(5).fill(0).reduce(arr=>{ arr.push(arr.length); return arr },[])
Ответ 6
Я не могу придумать способ с меньшим количеством символов, чем ~ 46:
var a=[];while(a.length<20)a.push(a.length+1);
Конечно, вы можете сделать из этого функцию.
Читая ваши комментарии о функции, вы можете сделать что-то вроде
var range = function (start, end) {
var arr = [];
while (start <= end) {
arr.push(start++)
}
return arr;
};
Затем range(1, 20)
вернет массив, как ожидалось.
Ответ 7
Если вы хотите как можно лучше сбрить персонажей без учета читаемости, это лучшее, что я могу сделать:
var x=[],i=0
while(i<20)
x[i]=i+++1
Не намного лучше, чем ваш.
Изменить:
На самом деле это работает лучше и сбрасывает пару символов:
var x=[],i=0
while(i<20)
x[i]=++i
Изменить 2:
И здесь моя запись для общей функции "диапазона" в наименьшем числе символов:
function range(s,e){var x=[];while(s<e+1)x.push(s++);return x}
Опять же, не пишите код таким образом.:)
Ответ 8
Я предполагаю, что это самый короткий путь:
var i=0, arr = [];
while (i++<20){
arr.push(i);
}
или сопоставление по "порочному" коду в EndangeredMassa answer:
var i,arr; while (i=i||1, (arr=arr||[]).push(i++)<20){}
Ответ 9
Вы всегда можете создать функцию...
function createNumArray(a, b) {
var arr = [],
i = a;
while((arr[arr.length] = i) < b) {i++}
return arr;
}
Это позволяет вам позже писать сжатый код, например...
var arr = createNumArray(1, 20);
Ответ 10
Насколько мне известно, опция использования цикла for, как вы упомянули, является наиболее сложной.
То есть
var x = [];
for (var i=1;i<=20;i++) {
x.push(i);
}
Ответ 11
var i = 0;
var x = [];
while (i++ < 20) x.push(i);
JSFiddle
Ответ 12
Я бы расширил прототип Array, чтобы упростить его доступ:
Array.prototype.range = function(start, end) {
if (!this.length) {
while (end >= start) {
this.push(start++);
}
} else {
throw "You can only call 'range' on an empty array";
}
return this;
};
var array = [].range(1, 20);
В то время как приведенное выше является ближайшим, о котором я могу думать в отношении синтаксического сахара, который вы ищете, вы можете попробовать CoffeeScript.
Он поддерживает обозначение, которое вы используете.
CoffeeScript:
test = [1..20]
alert test
Относится к JavaScript:
var test;
test = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20];
alert(test);
Вы можете опробовать живые примеры на своем сайте и увидеть преобразование, которое оно делает по мере ввода.
Просто нажмите ссылку TRY COFFEESCRIPT вверху, и вы получите консоль, где вы можете протестировать код.