我想创建一个过滤器类,其中有三种方法:name
,genre
和year
。我想根据多个条件过滤电影列表,其中每个对象都有name
,title
和year
。
我无法弄清楚如何做到这一点。例如:
Filter.name("Batman") & Filter.genre("Drama") | !Filter.year(2001)
我尝试将过滤器字段保留在列表[name => batman, genre=>drama]
中,依此类推,但运算符(尤其是or
(|
))正在困扰我。
我接受任何想法。
答案 0 :(得分:8)
试试这个:
让ary包含对象列表
ary.select{|obj| obj.name == 'batman' && obj.genre == 'drama' || obj.year != 2001}
我假设您在列表中有对象,请注意&&和||运营商的优先权
或者你期待这个?
class Filter
def self.search_by(ary, name, genre, year)
ary.select{|obj| obj.name == name && obj.genre == genre || obj.year != year}
end
end
ary = all_films # assume function returns all films
Filter.search_by(ary, 'batman', 'drama', 2001)
答案 1 :(得分:5)
您想要的功能自然适合Enumerable的select,Array继承。
因为你在谈论一个列表,AKA,数组,所以使用select来确定你的电影是否符合你的标准是很自然的,而不是将它们传递给方法。
单独的Filter类也不适合Ruby-way。考虑为电影列表对数组进行子类化,并添加一个以条件为参数的过滤方法。
以下是我编写该功能的方法,但是以一种我认为更像Ruby的方式来实现它:
require 'pp'
class Movies < Array
def initialize(*movies)
super(movies)
end
def filter(criteria={})
self.select{ |m|
criteria.all?{ |c, v|
m.send(c, v)
}
}
end
end
class Movie
def initialize(attributes={})
@movie = attributes
end
def name(t)
case t
when Regexp
@movie[:name][t]
when String
@movie[:name] == t
end
end
def genre(g)
@movie[:genre] == g
end
def year(y)
@movie[:year] == y
end
end
movies = Movies.new(
Movie.new(name: 'Batman', genre: 'Drama', year: 2001),
Movie.new(name: 'The Shawshank Redemption', genre: 'Drama', year: 1994),
Movie.new(name: 'Raiders of the Lost Ark', genre: 'Action', year: 1981)
)
pp movies.filter(year: 1981)
pp movies.filter(genre: 'Drama', year: 2001)
pp movies.filter(name: /redemption/i)
我在Movie类中使用了哈希,因为它更快。这也是一种更脏的方式,但它确实有效。
以下是运行代码的输出:
[#<Movie:0x007ff7b191ffb8
@movie={:name=>"Raiders of the Lost Ark", :genre=>"Action", :year=>1981}>]
[#<Movie:0x007ff7b1920260
@movie={:name=>"Batman", :genre=>"Drama", :year=>2001}>]
[#<Movie:0x007ff7b19200d0
@movie={:name=>"The Shawshank Redemption", :genre=>"Drama", :year=>1994}>]
过滤电影的实际流程符合我们通常编写Ruby代码的方式。它可以做得更好,但这是一个开始。
答案 2 :(得分:1)
|
是二元OR运算符
||
是逻辑OR运算符。如果两个操作数中的任何一个非零,则条件变为真。
所以你需要采取后者,
像这样:
Filter.name("Batman") && Filter.genre("Drama") || !Filter.year(2001)
有关详细信息,请参阅http://www.tutorialspoint.com/ruby/ruby_operators.htm。