Сегодня кто-то спросил меня, как вы создадите массив из N последовательных элементов, таких как [1,2,3,...,N] (должен начинаться с 1), где N предоставляется пользователем. Например, если N=10, то массив будет [1,2,3,4,5,6,7,8,9,10]. Кроме того, он хотел просуммировать элементы, так что если N=10, то результат будет 55.
Я сделал это следующим образом:
console.info(new Array(10).fill(1).map((x,y)=>x+y).reduce((x,y)=>x+y)).as-console-wrapper { max-height: 100% !important; top: 0; }
.as-console-row{background: #000;color: #fff;}
.as-console-row-code{font-size:24px!important}Я просто хочу спросить, как лучше всего решить ту же проблему и почему?
Лучший означает временную сложность и более быстрый способ
Я не думаю, что какая-либо полуразумная реализация будет иметь временную сложность больше, чем O(N)



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Вы можете удалить свою карту, так как вы просто суммируете, вы можете сделать это в самом уменьшении
console.info(new Array(10).fill(1).reduce((x,y,i) => x+y+i , 0)).as-console-wrapper { max-height: 100% !important; top: 0; }
.as-console-row{background: #000;color: #fff;}
.as-console-row-code{font-size:24px!important}Формула суммы первых n натуральных чисел — n * (n + 1)/2, что гораздо быстрее, чем возиться с массивами.
function getSum(n) {
return n * (n + 1) / 2;
}
console.info(getSum(10));Если вы все еще ищете решение «Лучший» с учетом времени выполнения, следующее решение в 55 раз быстрее, чем решение, опубликованное Нина (https://jsfiddle.net/vc1wmk6e/):
function range (first, last) {
var range = new Array(last - first + 1); range[0] = first;
for (var i = 1; range[i - 1] < last; i++) range[i] = first + i;
return range;
}
console.info(...range(1, 10));
console.info(range(1, 10).reduce((acc, x) => acc + x));Чтобы понять, почему это (примерно в 4,5 раза) быстрее, чем fill + map, нам нужно посмотреть на реализацию этих двух функций, чтобы вычислить их временную сложность. Я не готов сейчас углубляться в исходный код JS, но есть вероятность, что fill и map перебирают элементы массива. В этом случае временная сложность будет не менее O(2N), а функция range — O(N). Оставшееся дополнительное время может приходиться на вызовы функций, которые требуют поиска в памяти для нахождения соответствующего кода, но это чистое предположение :-|
это может напрямую дать мне диапазон, почему цикл будет быстрым? [...Array(size).keys()].map(i => i + startAt);
@SourabhSomani Еще один тест, включающий ваш код (test3): jsfiddle.net/qgte6r1u (test1 > test3 > test2). Спасибо за ваш голос, это справедливость :-)
@SourabhSomani Чтобы ответить на вопрос «почему цикл будет быстрым?», нам нужно проанализировать временную сложность оператора спреда (...), функции keys и функции map. Однако я не готов сейчас углубляться в исходный код JS, поэтому предоставил тестовые примеры :-)
Есть много вариантов. Это зависит от ваших критериев "лучшего".