Кратчайший способ создать массив целых чисел из 1..20 в JavaScript - PullRequest
42 голосов
/ 10 июня 2011

Какой самый краткий способ создать этот массив:

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 */ } и вы там.Вопрос в том, есть ли новые подходы к «кишкам».

Ответы [ 12 ]

68 голосов
/ 10 июня 2011

Подумав немного, это самая короткая реализация стандартной функции 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, что сокращает его до 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]

Добавленонекоторые тестовые примеры профилирования производительности: кажется, что все, кроме стандартного цикла for, в 10 раз медленнее, по крайней мере, на V8.https://jsperf.com/array-range-in-javascript (Конечно, ничего из этого не имеет значения, если вы все равно программируете в функциональном стиле и в любом случае вызовете каждый элемент вызовом функции.)

21 голосов
/ 10 апреля 2015

Это можно сделать с помощью функций ES6, которые в настоящее время поддерживаются только Firefox thou.Я нашел таблицу совместимости здесь: 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]

15 голосов
/ 10 июня 2011

Вы можете сделать это с помощью цикла while, где push происходит внутри условия. 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 голосов
/ 03 июня 2013

в то время как - путь

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. в то время как - это простосамый быстрый цикл;

  2. прямая настройка быстрее, чем push & concat;

  3. [] также быстрее, чем новый массив (10);

  4. это не намного более длинный код, чем все остальные

методы сохранения байтов:

  1. использовать аргументы в качестве полядля переменных в функции
  2. не используйте новые Array (), push (), concat (), если не нужно
  3. place "() {} ;," только при необходимости.
  4. используйте a, b, c, d ... в коротких функциях.

так что если вам нужна функция для этого

с началом, концом (диапазоном)

function range(a,b,c,d){d=[];c=b-a+1;while(c--)d[c]=b--;return d}

, то теперь range (3,7) возвращает [3,4,5,6,7]

Вы сохраняете здесь байты разными способами, и эта функция также очень быстрая, так как она не использует concat, push, new Array, и она сделана некоторое время -

1 голос
/ 10 сентября 2016

Использование ES6

numArr = Array(5).fill(0).reduce(arr=>{ arr.push(arr.length); return arr },[])

1 голос
/ 10 июня 2011

Вы всегда можете создать функцию ...

function createNumArray(a, b) {
   var arr = [], 
       i = a;

    while((arr[arr.length] = i) < b) {i++}
    return arr;
}

Позволяет позже написать краткий код, например ...

var arr = createNumArray(1, 20);
1 голос
/ 10 июня 2011

Полагаю, это кратчайший путь:

var i=0, arr = [];
while (i++<20){
  arr.push(i);
}

или связывание с «порочным» кодом в EndangeredMassa :

var i,arr; while (i=i||1, (arr=arr||[]).push(i++)<20){}
1 голос
/ 10 июня 2011

Если вы хотите сбить символы в любом случае без учета читабельности, это лучшее, что я могу сделать:

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}

Опять же, не пишите код таким образом.:)

1 голос
/ 10 июня 2011

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

0 голосов
/ 10 июня 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...