如何从数组中删除不需要的元素?

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",我需要排除那些名称中没有或类似于该名称的元素。所以它缩小到了"Nothing Else Matters"。如果用户输入字母"a",则数组中所有没有"a"的元素都将被删除。
它们将通过params[:text]传递进来。
我已经这样做了,它可以工作,但也许有更简洁的方法。
 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

metallica_tracks << "To Live is to Die"金属乐队音轨 << “生命就是死亡” - johnmcaliley
4
顺便提一下,你可以使用compact来代替delete_if {|x| x == nil} - vonconrad
4个回答

7

快速的 Ruby 变种是:

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"]

正如您在这段代码中看到的那样:我们只是将结果保存在变量中。 那么,在Rails中我们可以把数据存储在哪里呢? 您可以使用用户模型来存储,或者只是将这些数据存储在内存中。

创建类似下面的内容:

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)

我倾向于将状态记忆存储在类中,但不要忘记清除这个类的数据。


根据你想让用户执行的操作,你可能还需要从 data.match(word) 中转义正则表达式字符。否则,他们可以输入正则表达式来过滤结果。 - vonconrad
我同意你的观点。我只是想展示如何实现这个方法。有很多选项可以用来查找内容,例如正则表达式、单词匹配,或者像 command-t 这样的东西。 - vorobey

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?,您可以限制那种正则表达式的能力,就像其他人建议的那样,而不增加复杂性。在这个例子中,正则表达式有点像用机枪杀死苍蝇。

代码:
#我将数组重命名为歌曲列表,而不是艺术家
songs.select {|s| s.upcase.include?(query.upcase)}
如果您希望查询区分大小写,则可以省略upcase


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接