2016-10-18 64 views
0

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

这里是我想与之合作的数组:

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

哪有map这第一个和最后一个数组排序这个的?:

(2, 9) 
+0

'map'不能使用。 'map'的输出总是一个与输入数量相同的数组。你不能让它发射一个元组。 – Alexander

回答

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

如果你坚持使用减少,你可以做这样的:

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) 

每减少重复设置储油器向新的最小值(旧分钟越小和当前元素)以及新的最大值(旧的最大值和当前值中较大的一个)。

累加器的初始值被设定成使得:

  • 所述阵列中的任何元件进行比较作为除累加器的分钟
  • 所述阵列中的任何元件相比较更小大于蓄能器的最大
+0

使用最小/最大值而不是排序做O(n)次2,而不是一次一次排序和使用first/last,对吗? (如果这是一个10K +的数组) – TruMan1

+0

是的,2次通过。对于20K迭代的10K元素。排序需要〜132K – Alexander

+0

Reduce解决方案只执行一次,但这也是一个更昂贵的操作(由于关闭开销) – Alexander

0

你不” t需要一个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的,哎呦笑。我必须一直在冲浪错误的SO类别。我认为,除了您可能需要提供某种初始价值之外,该原则在快速原则上是相同的。

相关问题