2010-09-23 105 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,如果你想查询区分大小写