Уменьшить массив до кортежа первого и последнего элемента?

У меня есть массив, который я хотел бы сначала отсортировать, а затем вернуть первый и последний элемент отсортированного массива. Я думал, что могу использовать 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, упс, лол. Должно быть, я занимался серфингом не той категории. Я думаю, что принцип будет таким же быстрым, за исключением того, что вам, вероятно, нужно предоставить какое-то начальное значение.

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