将数组减少到第一个和最后一个元素的元组?

时间:2016-10-18 03:45:08

标签: arrays swift reduce

我有一个我想先排序的数组,然后返回排序数组的第一个和最后一个元素。我以为我可以使用reduce,但如果我没有初始值怎么办?

这是我正在尝试使用的数组:

let myNumbers = [4, 9, 6, 2, 3]

如何map这个到排序数组的第一个和最后一个?:

(2, 9)

2 个答案:

答案 0 :(得分:1)

方法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)

每次reduce迭代都会将累加器设置为新的min(旧的min和current元素中较小的一个)和新的max(旧的max和current中的较大者)。

累加器的初始值设置为:

  • 数组中的任何元素都比累加器的min
  • 数组中的任何元素都比累加器的最大值

答案 1 :(得分:0)

你不需要初始值来减少,它是可选的。

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}

编辑:刚刚注意到这是为了swift而不是javascript,哎呀lol。我一定是在浏览错误的SO类别。我认为原则在swift中是相同的,除非您可能需要提供某种初始值。