Уменьшить массив до кортежа первого и последнего элемента?
У меня есть массив, который я хотел бы сначала отсортировать, а затем вернуть первый и последний элемент отсортированного массива. Я думал, что могу использовать reduce
, но что, если у меня нет начального значения?
Вот массив, с которым я пытаюсь работать:
let myNumbers = [4, 9, 6, 2, 3]
Как может map
это к первому и последнему из отсортированного массива к этому?
(2, 9)
2 ответа
Способ 1: min()
/max()
Это самый простой способ:
let input = [4, 9, 6, 2, 3]
let output = (input.min(), input.max())
print(output) //(Optional(2), Optional(9))
Если вы уверены, что массив не пустой, вы можете безопасно развернуть дополнительные параметры:
let input = [4, 9, 6, 2, 3]
let output = (input.min()!, input.max()!) // (2, 9)
Этот подход делает 2 итерации по массиву. Это O(N)
, Если в другом месте не требуется отсортированный список, сортировка с последующим взятием первого / последнего будет хуже, как это было бы O(N * log_2(N))
,
Способ 2: reduce()
Если вы настаиваете на использовании Reduce, вы можете сделать это следующим образом:
let input = [4, 9, 6, 2, 3]
let output = input.reduce((min: Int.max, max: Int.min)){
(min($0.min, $1), max($0.max , $1))
} //(2, 9)
Каждая итерация сокращения устанавливает для аккумулятора новый минимум (меньший из старого элемента min и current) и новый максимум (больший из старого max и тока).
Начальные значения аккумулятора установлены так, что:
- Любой элемент в массиве сравнивается как меньше, чем минимум аккумулятора
- Любой элемент в массиве сравнивается с максимальным значением аккумулятора
Вам не нужно initialValue для снижения, это необязательно.
var foo = [1, 40, 20, -20, 50];
var reducer = function(prev, curr, i, arr){return [prev[0] <= curr ? prev[0] : curr, prev[1] >= curr ? prev[1] : curr]};
var baz = foo.reduce(reducer); // [-20, 50]
Или, может быть, так:
var foo = [1, 40, 20, -20, 50];
var reducer = function(prev, curr, i, arr){return {min: prev.min <= curr ? prev.min : curr, max: prev.max >= curr ? prev.max : curr}};
var baz = foo.reduce(reducer); // {min: -20, max: 50}
Редактировать: Просто заметил, что это для быстрого, а не javascript, упс, лол. Должно быть, я занимался серфингом не той категории. Я думаю, что принцип будет таким же быстрым, за исключением того, что вам, вероятно, нужно предоставить какое-то начальное значение.