2016-10-18 89 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類別。我認爲,除了您可能需要提供某種初始價值之外,該原則在快速原則上是相同的。

相關問題