Check if string contains element in Array - ruby-on-rails

I'm using Rails and learning ActiveRecord and I came across a vexing problem. Here's an array in my model:
#sea_countries = ['Singapore','Malaysia','Indonesia', 'Vietnam', 'Philippines', 'Thailand']
And here's my ActiveRecord object:
#sea_funding = StartupFunding.joins(:startup)
.where('startups.locations LIKE ?', '%Singapore%')
What I'm trying to do is to return a result where a string in the 'locations' column matches any element in the Array. I'm able to match the strings to each element of an Array (as above), but I'm not sure how to iterate over the whole Array such that the element is included as long as there's one match.
The intent is that an element with multiple locations 'Singapore,Malaysia' would be included within #sea_funding as well.
Well, don't ask me why 'locations' is set as a string. It's just the way the previous developer did it.

You use an IN clause in your .where filter:
#sea_funding = StartupFunding.joins(:startup)
.where(["startups.locations IN (?)", #sea_countries])

#sea_countries.include?(startups.locations)
This will return a boolean TRUE if the value of the locations column in startups can be found in the sea_countries array, false if it is absent.

Could this work for you?
first = true
where_clause = nil
sea_countries.each do |country|
quoted_country = ActiveRecord::Base.connection.quote_string(country)
if first
where_clause = "startups.locations LIKE '%#{quoted_country}%' "
first = false
else
where_clause += "OR startups.locations LIKE '%#{quoted_country}%' "
end
end
#sea_funding = StartupFunding.joins(:startup)
.where(where_clause)

Related

Ruby array - comparison customer_id with an array

I have array of numbers which means governings to acces customer:
Controller :
#user_got_these_governings = current_user.governings.map{ |governing| governing.customer_id}
which_customer_is_selected = params[:user][:customer_id]
i need to compare customer_id with an array of numbers:
customer_id: 1
Governings: [7,9,6,2,3,1]
if Governings match with customer_id = true
if not = false
Something like
which_customer_is_selected = #user_got_these_governings.include?(params[:user][:customer_id].to_i)
to_i because you are probably receiving a string in the parameter and you are comparing it with an array of integers.
I think that cleanest way to do it is use in? method.
governings = [7,9,6,2,3,1]
params[:user][:customer_id].to_i.in? governings
=> true
Another possible way to do it is by using .member? method which tells whether an element is a member of the array or not.
Governings: [7,9,6,2,3,1]
Governings.member? params[:user][:customer_id].to_i
=> true

Searching array of objects for item in Ruby

I am trying to search through an array of objects for a value, but am having trouble getting the find_index to work. In my code below, I am trying to search for the name (joseph) in the array. Is this the best way? I want to return that object after I search and find it.
name = "joseph"
array = [{"login":"joseph","id":4,"url":"localhost/joe","description":null},
{"login":"billy","id":10,"url":"localhost/billy","description":null}]
arrayItem = array.find_index {|item| item.login == name}
puts arrayItem
Your array contains a Hash, with keys that are symbols (in hashes, key: value is a shorthand for :key => value). Therefore, you need to replace item.login with item[:login]:
name = "joseph"
array = [{"login":"joseph","id":4,"url":"localhost/joe","description":nil},
{"login":"billy","id":10,"url":"localhost/billy","description":nil}]
arrayIndex = array.find_index{ |item| item[:login] == name }
puts arrayIndex
The code above retrieves the index at which the sought object is in the array. If you want the object and not the index, use find instead of find_index:
arrayItem = array.find{ |item| item[:login] == name }
Also, note that in Ruby, null is actually called nil.

Simplifying an expression using .map

Below I have an example active record query using a bunch of each iterators
user.user_spells.each do |us|
us.spell.buff_effects.where(stat_effected:'gold').each do |be|
value = value + be.value
end
end
I would like to use .map to return a list of all the results so I can do it essentially in one line.
I came up with:
user.user_spells.map { |us| us.spell.buff_effects.where(stat_effected:stat_effected) }.each do |be|
value = value + be.value
end
However... the .map block returns some empty arrays. Not sure how to write it correctly.
Any help would be appreciated! Thanks
Probably along these lines, if what you want is the sum of values in the end:
value =
user.user_spells.flat_map do |us|
us.spell.buff_effects.where(stat_effected:'gold').map(&:value)
end.reduce(&:+)

Lua - Table.hasValue returning nil

I have a table something like this:
table = {milk, butter, cheese} -- without "Quotation marks"
I was searching for a way to check if a given value is in the table or not, and found this:
if table.hasValue(table, milk) == true then ...
but it returns nil, any reason why? (it says .hasValue is invalid) or can I get an alternative to check if value exists in that table? I tried several ways like:
if table.milk == true then ...
if table[milk] == true then ...
All of these returns nil or false.
you can try this
items = {milk=true, butter=true, cheese=true}
if items.milk then
...
end
OR
if items.butter == true then
...
end
A Lua table can act as an array or as an associative array (map).
There is no hasValue, but by using a table as an associative array you can easily implement it efficiently:
local table = {
milk = true,
butter = true,
cheese = true,
}
-- has milk?
if table.milk then
print("Has milk!")
end
if table.rocks then
print("Has rocks!")
end
You have a few options here.
One, is to create a set:
local set = {
foo = true,
bar = true,
baz = true
}
Then you check if either of these are in the table:
if set.bar then
The drawback to this approach is that you won't iterate over it in any specific order (pairs returns items in an arbitrary order).
Another option would be to use a function to check each value in a table. This'll be very slow in large tables, which brings us to back to a modification of the first option: A reverse lookup generator: (This is what I'd recommend doing -- unless your set is static)
local data = {"milk", "butter", "cheese"}
local function reverse(tbl, target)
local target = target or {}
for k, v in pairs(tbl) do
target[v] = k
end
return target
end
local revdata = reverse(data)
print(revdata.cheese, revdata.butter, revdata.milk)
-- Output: 3 2 1
This'll generate a set (with the added bonus of giving you the index where the value was in your original table). You can also put the reverse into the same table as the data was in, but this won't go well with numbers (and it'll be messy if you need to generate the reverse again).
If you write table = {milk=true, butter=true, cheese=true}, then you can use if table.milk == true then ....

getting a column by "name" in an activerecord

I have a select statement that returns a field in a table.
records = Product.select("DISTINCT #{iFieldName}").where("id in (0, #{iInClaws})" )
I want to convert the data in the database to an array to be used later.. say as another inClaws.
records.each{|record| fieldArray << record.?????}
I have two questions.
Is there a better way to do this?
If there's not, then how do I get the data out of the field.
Thanks to all..
After everyone came to help my final method looked like this.
def self.getFieldArray(iFieldName, iIDsInClaws, iIdFieldName = 'id')
records = self.select("DISTINCT #{iFieldName}").where("#{iIdFieldName} in (#{iIDsInClaws})" )
return records.map{|record| record.send(iFieldName)};
end
fieldArray = records.map(&:iFieldName)
Or
res = records.map{|r| r.send(iFieldName)}
records.each{|record| fieldArray << record.send(iFieldName)}

Resources