Techioz Blog

処理メソッド、条件付きの場合は単純であるべきであるという問題

概要

Ruby で、引数で渡される proc に基づいて配列を分割するメソッドを作成する予定です。私の完全な方法は次のとおりです。

def proctition(arr, &prc)
    failed = []
    passed = []
    debugger
    if arr != arr.flatten
        passed.push(*arr[0])
        arr[1].each_with_index do |ele, i|
            if prc.call(ele)
                passed.push(ele)
                remainder = arr[1].pop(arr.size - i + 1)
                self.proctition([passed, remainder], &prc)
            else
                failed.push(ele)
                remainder = arr[1].pop(arr.size - i + 1)
                self.proctition([passed, remainder], &prc)
            end
        end
    else
        [*passed, *failed]
    end
end

私の知る限り、配列から要素を選択的に削除し、最後のデフォルトの 1 または指定した桁数に対して Pop() が行うように削除された要素を評価するメソッドはありません。以前の方法で再帰を有利に使用する方法を理解することができました。解決策はこの軌道に沿っていると感じています。私の戦略は、再帰の各レベルでスコープを維持する成功した配列と失敗した配列を設定することであり、メソッドへの再帰呼び出しで 2D 配列を渡し、最初に配列かどうかの簡単なチェックを追加しました。 2Dかどうか arr != arr. flatten そして、このプログラムの実行中に pry を介してこの正確なステートメントを実行したところ、このステートメントが元のメソッド呼び出しで評価されると予想された結果が得られました: false、つまり、この配列は、 ’ を実行したときの配列と同じです。同じ名前のメソッドを呼び出してフラット化します。そして、この if ブロック内で、ソートとプルーニング、およびプルーニングされた配列の再帰呼び出しを実行します。ただし、実際の実行では、else ブロックに進んで空の配列の連結を返すため、逆に評価する必要があります。

解決策

配列を変更しようとしたり再帰を使用しようとしたりしながら、なぜ配列を反復処理するのかは不明です。これは、非常に単純な問題に対して、非常に考え抜かれ、過度に複雑な解決策のように見えます。

def proctition(arr, &prc)
  good, bad = [], []
  arr.each do |x| 
    if prc.call(x)
      good << x 
    else 
      bad << x 
    end 
  end
  [*good, *bad]
end

そしていま:

irb(main):012:0> proctition([1, 2, 3, 4], &:even?)
=> [2, 4, 1, 3]