对象数组的类SQL语法

时间:2014-01-21 12:11:12

标签: ruby-on-rails ruby

我有一个对象数组。对于此数组中的某些对象字段,我需要使用类似SQL的条件WHERE字段,如'%value%'。 怎么做?

编辑: 例如,我有Users的数组,我需要找到first_name like ikelike 123的所有用户。

Edited2: 我需要一种方法来获取Users first_nameUsers一样的smth和电子邮件,例如smth来自我Users ARRAY first_nameemailUsers

Edited3: 我的所有用户都在数据库中。但是我有一些业务逻辑,在这个逻辑的最后我有ike的数组。接下来,我需要使用一些文本过滤此数组:first_name 123和{{1}}电子邮件。怎么做?

3 个答案:

答案 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)