2017-04-04 66 views
1

我有一個對象數組,它按照此對象的一個​​屬性進行排序,並且我想在該位置插入另一個對象,該位置由該屬性確定的對象。基於數組內容在特定位置插入數組Ruby

基本上是這樣的:
foo = [User(score: 10), User(score: 8), User(score: 5), User(score: 1)]
這陣中,我想插入:
bar = User(score: 6)
在正確的索引,所以在這種情況下,在指數2

我能推到數組,然後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使用(... || -1),這意味着該值是arr的最後一個元素之後插入。見String#insert

+1

嘿卡里,我不知道你爲什麼被低估,但這是最好的答案。默認的'-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。 但我認爲這絕對是正確的做法!謝謝Rahul :) – Jeroen

+0

好的。剛剛編輯來解釋這種情況。 – Rahul