2016-10-18 20 views
0

私は最初にソートしたい配列を持っていて、ソートされた配列の最初と最後の要素を返します。私はreduceを使うことができると思ったが、もし私が初期値を持っていなければどうなるだろうか?ここで最初と最後の要素のタプルに配列を減らしますか?

は、私が一緒に仕事しようとしている配列です:

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

どうmapこれを最初にし、これにソートされた配列の最後の?:

(2, 9) 
+0

'map'は使用できません。 'map'の出力は常に入力と同じ数の要素を持つ配列です。タプルを発行することはできません。 – Alexander

答えて

1

方法1:min()/max()

これが最も簡単な方法です:

:あなたは、配列が空ではないと確信している場合は、あなたが安全にoptionalsをアンラップを強制することができ

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) 

それぞれの反復を減らす古い分の少ない(新しい分にアキュムレータを設定し、現在の要素)と、新しいmax(古いmaxとcurrentのうち大きい方)を返します。アレイ内の任意の要素は、アキュムレータの分

  • よりも小さいように比較

    • アレイ内の任意の要素は、アキュムレータの最大
    • よりも大きいように比較:アキュムレータの

      初期値となるように設定されています

  • +0

    ソートの代わりにmin/maxを使うと、一度ソートしてfirst/lastを使ってO(n)回2回するのではなく、right? (これが10K +の配列の場合) – TruMan1

    +0

    はい、2パスします。 20Kの反復回数を持つ10K要素の場合並べ替えには〜132Kがかかります – Alexander

    +0

    reduceソリューションは1回のパスを行いますが、(クロージャのオーバーヘッドのために) – Alexander

    0

    あなたドン」とすることができますreduceにはinitialValueが必要ですが、オプションです。

    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} 
    

    編集:このような

    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] 
    

    それとも笑おっと、これは迅速でないjavascriptのためのものです気づきました。私は間違ったSOのカテゴリーをサーフィンしていたに違いない。私は原則は、おそらく初期値のいくつかの種類を提供する必要があることを除いて、迅速に同じだろうと思う。

    関連する問題