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 вверху, и вы получите консоль, где вы можете протестировать код.