2017-04-04 10 views
1

このオブジェクトの属性の1つでソートされたオブジェクトの配列があり、その属性によって決定される位置に別のオブジェクトを挿入したいオブジェクトの配列の内容に基づいて特定の位置に配列に挿入するRuby

基本的には、のようなもの:正しいインデックスで
bar = User(score: 6)
を、インデックス2

で、この場合、私はそれをプッシュすることができるように:
foo = [User(score: 10), User(score: 8), User(score: 5), User(score: 1)]
そしてそのアレイでは、私が挿入したいです配列にしてsort_by、しかし、私はこの問題(インデックスを定義するブロックを渡すことができるいくつかの種類の挿入メソッド)のためのより良い解決策があるのだろうかと思っていた。

ありがとうございます。

+0

私はこのソリューションは、あなたの目的のためには良いかもしれないと思う:http://stackoverflow.com/questions/23481725/using-bsearch-to-find-index-for-inserting-new-element-into-sorted-array –

答えて

0

コード

def insert_new(arr, new_instance) 
    arr.insert(arr.index { |instance| new_instance.score >= instance.score } || -1, 
    new_instance) 
end 

class A 
    def initialize(user, score) 
    @user, @score = user, score 
    end 
end 

arr = [A.new("Hank", 10), A.new("Lois", 8), A.new("Billy-Bob", 6), 
     A.new("Trixy", 4)] 
    #=> [#<A:0x007fad7b02fd70 @user="Hank", @score=10>, 
    # #<A:0x007fad7b02fcf8 @user="Lois", @score=8>, 
    # #<A:0x007fad7b02fc80 @user="Billy-Bob", @score=6>, 
    # #<A:0x007fad7b02fbe0 @user="Trixy", @score=4>] 

insert_new(arr, A.new("Hubert", 7)) 
    #=> [#<A:0x007fad7a027450 @user="Hank", @score=10>, 
    # #<A:0x007fad7a0273b0 @user="Lois", @score=8>, 
    # #<A:0x007fad7a850b90 @user="Hubert", @score=7>, 
    # #<A:0x007fad7a027310 @user="Billy-Bob", @score=6>, 
    # #<A:0x007fad7a027270 @user="Trixy", @score=4>] 
insert_new(arr, A.new("Zelda", 2)) 
    #=> [#<A:0x007fad7a027450 @user="Hank", @score=10>, 
    # #<A:0x007fad7a0273b0 @user="Lois", @score=8>, 
    # #<A:0x007fad7a850b90 @user="Hubert", @score=7>, 
    # #<A:0x007fad7a027310 @user="Billy-Bob", @score=6>, 
    # #<A:0x007fad7a027270 @user="Trixy", @score=4>, 
    # #<A:0x007fad7b876128 @user="Zelda", @score=2>] 
insert_new(arr, A.new("Slim", 8)) 
    # Slim is inserted between Hank and Lois 
insert_new(arr, A.new("Rhonda", 8)) 
    # Rhonda is inserted between Hank and Slim 

ていることに注意してくださいゼルダ最後に挿入されました。その場合、

arr.index { |instance| new_instance.score >= instance.score } #=> nil 

はそう指標-1値がarrの最後の要素の後に挿入されることを意味し、(... || -1)を使用しました。 String#insertを参照してください。

+1

こんにちはキャリー、私はなぜあなたがdownvotedされているのか分からないが、これは最高の答えです。デフォルトの '-1'は本当にスマートです。包括的な例もありがとうございます。努力をいただきありがとうございます!あなたは本当に私を助けました:) – Jeroen

1

完全な並べ替えを避けたい場合は、インデックスを見つけて挿入できます。以下のような何か -

insert_index = foo.index { |x| x.score <= new_user.score } || -1 
foo.insert(insert_index, new_user) 
+1

これは確かに賢い解決策です!ここでの唯一の問題は、new_user.scoreが他のスコアよりも常に小さい場合、それは必要なように最後に挿入されないことです。 Cary Swovelandも同様の答えを返し、foo.indexがnilを返す場合はデフォルト値-1を追加しました。 しかし、これは間違いなく正しいアプローチです、と私は思います!ありがとうラフル:) – Jeroen

+0

良いキャッチ。その事件を説明するために編集されました。 – Rahul

関連する問題