我有一个对象数组。对于此数组中的某些对象字段,我需要使用类似SQL的条件WHERE字段,如'%value%'。 怎么做?
编辑:
例如,我有Users
的数组,我需要找到first_name
like
ike
和like
123
的所有用户。
Edited2:
我需要一种方法来获取Users
first_name
和Users
一样的smth和电子邮件,例如smth来自我Users
的 ARRAY 。 first_name
有email
和Users
。
Edited3:
我的所有用户都在数据库中。但是我有一些业务逻辑,在这个逻辑的最后我有ike
的数组。接下来,我需要使用一些文本过滤此数组:first_name
123
和{{1}}电子邮件。怎么做?
答案 0 :(得分:1)
arr = %w[hello quick bool boo foo]
arr.select { |x| x.include?("foo") }
=> ["bool", "boo", "foo"]
或者在你的情况下,如果你有一个对象数组,你可以这样做:
x.first_name.include?("foo") && x.email.include?("123")
要进行更多自定义,您可以使用带有Regexep s
的数组#选择答案 1 :(得分:1)
如果你可以使用ruby方法做这样的事情:
User = Struct.new(:email, :first_name) # Just creating a cheap User class here
users = [
User.new('1@a.com' , 'ike'),
User.new('123@a.com', 'bob'),
User.new('123@a.com', 'ike'),
]
# results will be an array holding only the last element in users
results = users.find_all do |user|
user.email =~ /123/ and
user.first_name =~ /ike/
end
编写自己的sql解析器似乎是一个非常糟糕的主意,但如果你真的需要解析简单的SQL where子句,你可以做这样的事情:
User = Struct.new(:email, :first_name) # Just creating a cheap User class here
users = [
User.new('1@a.com' , 'ike'),
User.new('123@a.com', 'bob'),
User.new('123@a.com', 'ike'),
]
def where(array, sql)
sql = sql.gsub(/\s+AND\s+/, ' ') # remove AND's
terms = Hash[ *sql.split(/\s+LIKE\s+| /) ] # turn "a LIKE 'b'" into {'a': "'b'"}
array.find_all do |item|
terms.all? do |attribute, matcher|
matcher = matcher.gsub('%', '.*') # convert %
matcher = matcher.gsub(/^['"]|["']$/, '') # strip quotes
item.send(attribute) =~ /^#{matcher}$/
end
end
end
# results will be an array holding only the last element in users
results = where(users, "first_name LIKE '%ike%' AND email LIKE '%123%'")
这仅适用于仅包含由LIKE
连接的AND
语句的where子句。添加对所有有效SQL的支持是留给读者的练习(或者更好的是,只留下)。
答案 2 :(得分:0)
我已经构建了一个ruby gem uber_array来为你想要尝试的Hashes或Objects数组启用类似sql的语法。
require 'uber_array'
# Array of Hash elements with strings as keys
items = [
{ 'name' => 'Jack', 'score' => 999, 'active' => false },
{ 'name' => 'Jake', 'score' => 888, 'active' => true },
{ 'name' => 'John', 'score' => 777, 'active' => true }
]
uber_items = UberArray.new(items)
uber_items.where('name' => 'John')
uber_items.where('name' => /Ja/i)
uber_items.like('ja')
uber_items.where('name' => %w(Dave John Tom))
uber_items.where('score' => 999)
uber_items.where('score' => ->(s){s > 900})
uber_items.where('active' => true, 'score' => 800..900)