Лучший способ последовательно заполнить массив и добавить все элементы массива

Сегодня кто-то спросил меня, как вы создадите массив из 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}

Я просто хочу спросить, как лучше всего решить ту же проблему и почему?

Есть много вариантов. Это зависит от ваших критериев "лучшего".

CertainPerformance 12.03.2019 19:17

Лучший означает временную сложность и более быстрый способ

Sourabh Somani 12.03.2019 19:18

Я не думаю, что какая-либо полуразумная реализация будет иметь временную сложность больше, чем O(N)

CertainPerformance 12.03.2019 19:18
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
2
3
266
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Вы можете создать массив с Array.from, используя объект с длиной в качестве свойства и сопоставить увеличенные индексы.

var length = 10,
    array = Array.from({ length }, (_, i) => i + 1),
    sum = array.map((s => v => s += v)(0));

console.info(...array);
console.info(...sum);

Вы можете удалить свою карту, так как вы просто суммируете, вы можете сделать это в самом уменьшении

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);

Sourabh Somani 13.03.2019 09:42

@SourabhSomani Еще один тест, включающий ваш код (test3): jsfiddle.net/qgte6r1u (test1 > test3 > test2). Спасибо за ваш голос, это справедливость :-)

user1636522 13.03.2019 09:46

@SourabhSomani Чтобы ответить на вопрос «почему цикл будет быстрым?», нам нужно проанализировать временную сложность оператора спреда (...), функции keys и функции map. Однако я не готов сейчас углубляться в исходный код JS, поэтому предоставил тестовые примеры :-)

user1636522 13.03.2019 09:59

Другие вопросы по теме