2010-09-23 67 views
4

好吧,我有一個看起來像這樣的數組。如何從數組中刪除不需要的東西?

["Enter Sandman", "One", "Nothing Else Matters", "Master of Puppets", "The Unforgiven", "The Day That Never Comes", "For Whom the Bell Tolls", "Fade to Black", "Sad But True", "Wherever I May Roam", "Turn the Page", "I Disappear", "Fuel", "Cyanide", "Seek & Destroy", "Whiskey In the Jar", "All Nightmare Long", "Battery", "Welcome Home (Sanitarium)", "The Unforgiven III", "The Unforgiven II", "King Nothing", "Ride the Lightning", "No Leaf Clover", "Until It Sleeps", "...And Justice for All", "Blackened", "The Memory Remains", "Hero of the Day", "The Four Horsemen", "Orion", "Creeping Death", "St. Anger", "Harvester of Sorrow", "Don't Tread on Me", "Broken, Beat & Scarred", "Disposable Heroes", "Fight Fire With Fire", "The End of the Line", "Trapped Under Ice", "Of Wolf and Man", "Whiplash", "My Apocalypse", "Suicide & Redemption", "The Shortest Straw", "Tuesday's Gone"] 

此陣列由該命令

artists = search_object.map{|x| x["trackName"]}.uniq.delete_if {|x| x == nil} 

這個工作得很好,但產生的,我需要過濾掉一些更多的元素。用戶將輸入文本字段,當他們鍵入我需要縮小結果。所以例如,如果用戶輸入字符串「Matters」,我需要去除名稱中不包含那些元素或名稱的元素。所以它簡單地歸結爲「無關緊要」。如果用戶輸入字母「a」,那麼陣列中沒有「a」的所有其他人都將被刪除。

他們會來與PARAMS [:文]

我做到這一點,它的工作,但也許有一個更清潔的方式

query = params[:term] 
artists = search_object.map{|x| x["trackName"]}.uniq.delete_if {|x| x == nil} 
filtered = [] 
artists.each do |artist| 
    filtered << artist if artist.include?(query) 
end 
+0

metallica_tracks << 「活着就是死」 – johnmcaliley 2010-09-23 02:08:56

+3

一點題外話了,你可以使用'compact'而不是'delete_if {| x | x == nil}'。 – vonconrad 2010-09-23 02:25:10

回答

6

快速紅寶石變種是:

albums = ["hello kitty", "bad day", "all is good", "day is okay"] 

def filter_word_in(word,array) 
    array.delete_if { |data| !data.match(word) } 
    return array 
end 

result1 = filter_word_in("y", albums) 
puts result1.inspect # => ["hello kitty", "bad day", "day is okay"] 

result2 = filter_word_in("ay", result1) 
puts result2.inspect # => ["bad day", "day is okay"] 

result3 = filter_word_in("day", result2) 
puts result3.inspect # => ["bad day", "day is okay"] 

result4 = filter_word_in("day i",result3) 
puts result4.inspect # => ["day is okay"] 

如何在此代碼中看到:我們只是將結果保存在變量中。那麼,我們可以在哪裏存儲我們的數據在軌道上? 您可以使用user_model,或者您可以將這些數據存儲在內存中。

創建這樣的事情:

class UserSongMemory 
    attr_accessor :memory 

    def initialize 
     @memory = [] 
    end 

    def push(id, data) 
     @memory << {id => data} 
    end 

    def pop(id) 
     @memory.delete_if {|obj| obj.id == id} 
    end 
end 

user_memory = UserSongMemory.new 
user_memory.add(@user.id, params[:inputed_string]) 

# after our calculations 
user.pop(@user.id) 

我寧願存儲級內存的狀態,但不要忘了清理此類數據

+0

根據你想允許用戶做什麼,你可能也想從'data.match(word)'中轉義正則表達式字符。否則,他們可以輸入正則表達式來過濾結果。 – vonconrad 2010-09-23 02:29:07

+0

我同意你的意見。我只是想展示如何做到這一點的方法。如何查找內容有多種選擇 - 正則表達式,單詞匹配或類似command-t%的選項) – vorobey 2010-09-23 16:47:10

1

我這樣做:

term, fname = params[:term], "trackName" 
filtered = search_object.map {|x| x[fname] if x[fname].match(term) }.compact.uniq 

這種方法消除了兩個循環的需要,一個用於收集和其他選擇。根據您的要求,uniqcompact方法在那裏。

0

Array類爲您提供「reject」方法以從您的陣列中刪除不需要的元素。

0

這裏有一個稍微不同的方法和我的推理。

原因:
我想象在一個文本框,讓您輸入您想要選擇的一個子向下過濾到該項目的網頁列表。因此,我的假設是你的用戶只會輸入一個子字符串。這些不是高級用戶,他們會根據他們想要的曲目進行正則表達式匹配。通過使用selectinclude?,您可以按照人們的建議限制該正則表達式的能力,而不會增加複雜性。在這個例子中,正則表達式有點像使用機槍殺死蒼蠅。

代碼:
#I renamed the array, since it was a list of songs, not artists
songs.select {|s| s.upcase.include?(query.upcase)}
你可以離開upcase,如果你想查詢區分大小寫