Parse comma separated values - ruby-on-rails

I would like to parse comma separated values from a url parameter in Ruby on Rails.
For example how to parse the following?
http://example.com/?fields=1,2,3
I would like to be able to use params[:fields] in my controller. Is that creating an array? Should I use for loop?

foo = params[:fields].split(',')

> a = "1,2,3"
=> "1,2,3"
> a.split(',')
=> ["1", "2", "3"]
> a.split(',').each {|element| p element}
"1"
"2"
"3"
=> ["1", "2", "3"]
> a.split(',').map(&:to_i)
=> [1, 2, 3]

foo = params[:fields].split(',').map { |i| Integer(i) }
This will convert the fields params to integers and will validate your fields params if you want them to be integers.An Argument error will raise if that's not the case.(ex. http://example.com/?fields=1,2,test)

Related

Filter Array in Ruby on Rails with only to_s elements

I have this code that works well
def self.select_some_elements(some_value)
return elements.select { |element| element.some_value > some_value}
end
This code returns an array of elements class instances/objects. However, I would like to return the array of element.to_s instances/propeties, not the whole class objects, just strings/string properties
Is there a quick way to do it without going extra steps?
Introduction:
So, what you have achieved is a set (array in this case) of objects, which is great. What you have to do now is to transform this set into a different one: namely, replace each object with what that object's method to_s returns. There's a perfect method for that, called map. It goes through all the items, calls a block with each item as an argument and puts in the resulting array what the block has returned:
Open irb console and play around:
>> [1,2,3].map{|x| 1}
=> [1, 1, 1]
>> [1,2,3].map{|x| x+1}
=> [2, 3, 4]
>> [1,2,3].map{|x| "a"}
=> ["a", "a", "a"]
>> [1,2,3].map{|x| x.to_s}
=> ["1", "2", "3"]
>> [1,2,3].map(&:to_s)
=> ["1", "2", "3"]
The last transformation seems to be what you need:
The answer:
Add .map(&:to_s) at the end like this
def self.select_some_elements(some_value)
return elements.select { |element| element.some_value > some_value}.map(&:to_s)
end
.map(&:to_s) is a short version of .map { |element| element.to_s }. And you can read about Arra3#map in the docs
And when you wrap your head around the #map, check out Stefan's answer which shows how select{}.map can be "compressed" into one filter_map call (doing both things: filter, and mapping in one iteration over the set instead of two).
Starting with Ruby 2.7 there's filter_map:
elements = [1, 2, 3, 4, 5]
elements.filter_map { |e| e.to_s if e > 2 }
#=> ["3", "4", "5"]

Rails, delete string-quotes from array, without turning it to a string

I have a method, that takes an array as argument, such as:
a = ["title", "item"]
I need to get rid of the " but I have difficulties to do so.
My goal is to achieve the following:
a = [title, item]
Two possible solutions were presented here:Getting rid of double quotes inside array without turing array into a string
eval x.to_s.gsub('"', '')
# => [1, 2, 3, :*, :+, 4, 5, :-, :/]
and
x=["1", "2", "3", ":*", ":+", "4", "5", ":-", ":/"]
=> ["1", "2", "3", ":*", ":+", "4", "5", ":-", ":/"]
x.map{|n|eval n}
=> [1, 2, 3, :*, :+, 4, 5, :-, :/]
I tried both of these solutions, but It always leads to this error:
undefined local variable or method `title'
How do I get rid off these " quotes in an array?
Edit:
I need to alter an array. This is what I am trying to do:
a = ["title", "item"]
should change to something like:
a = [model_class.human_attribute_name(:title), model_class.human_attribute_name(:title)]
(It's about translations).
This code is in a model.rb, maybe that helps.Here is my full code:
def humanifier(to_translate_array)
translated = []
to_translate_array.each do |element|
translated.push("model_class.human_attribute_name(:#{element})")
end
return translated
end
It looks like you want to translate strings into symbols, you can do that with #to_sym
to_translate_array.each do |element|
translated.push("model_class.human_attribute_name(#{element.to_sym})")
end
Or if you actually want the translated value, (and not just a string "model_class.human...")
to_translate_array.each do |element|
translated.push(model_class.human_attribute_name(element.to_sym))
end
"title" is a string, :title is a symbol.

How to add elements of an array to another array and remove duplicates

I'm trying to create a json file in ruby on rails that has a specific format like so:
{"nodes":["1","2","3"],"edges":[["1","3"],["2","3"],["2","1"]]}
I have a method in my model that is as follows:
def self.joinup(id)
c = Challenge.find(id)
result={}
user_ids = c.users.pluck(:id)
result["nodes"] = user_ids.collect(&:to_s)
result["edges"] = Relationship.where(follower_id: user_ids).map{|h| [h.follower_id.to_s, h.followed_id.to_s]}
result["nodes"] = result["nodes"]|result["edges"]
result
end
and this produces:
{"nodes":["1","2","3","3","3"["4","5"],["5","6"]],"edges":[["4","5"],["5","6"]]}
whereas was I want is:
{"nodes":["1","2","3","4","5","6"],"edges":[["4","5"],["5","6"]]}
In rails you can use the array method flatten which returns an array with one dimension, like this
array = ["1", "2", "3", ["2", "3", "4"], "5"]
array.flatten #=> ["1", "2", "3", "2", "3", "4", "5"]
After that you can use the method uniq which returns all the different values inside your array, so this will return this as a result
array.flatten.uniq #=> ["1", "2", "3", "4", "5"]
Also, this method can be used with the bang (!) operator, which change the original array with the return values, so it will be like this
array.flatten!.uniq!
Hope it helps :D
You merged the contents in result["edges"] in this line:
result["nodes"] = result["nodes"]|result["edges"]
after that, you may firstly flatten the array and then uniq:
result["nodes"].flatten!.uniq!
result
You can use flatten with uniq:
result["nodes"] = (result["nodes"] | result["edges"].flatten).uniq

how do I invert my hash (switch key/value) and group by value

I have a hash in rails like so:
{"unique_id" => "1",
"unique_id2" => "2",
"unique_id3" => "n"}
Each unique key has a count that can be a number 1-20. What I would like to do is have a hash that looks like this:
{"1" => ["unique_id", "unique_id2"],
"2" => ["unique_id3"],
"3" => ["unique_id4", "unique_id5", "uniqueid6"]}
How would I go about doing that with a hash?
Not too hard!
hash = { "unique_id" => "1",
"unique_id2" => "2",
"unique_id3" => "n"
}
new_hash = hash.each_with_object({}) { |(k,v), h| (h[v] ||= []) << k }
each_with_object({}) is just an each loop with a blank hash
||= [] means if the hash doesn't have a value for v, set it equal to an empty array
<< k pushes the key onto the array
Try this:
h.group_by{|k,v| v }.each{|k,v| v.map!(&:first) }
group_by takes your hash and groups it by value
each iterates over the result hash
map! maps the first elements of the result value arrays, since group_by on a Hash returns two-dimensional Arrays with the structure [key, value]

Ruby on Rails: short hand to put commas in between elements in an array?

users_allowed_to_be_viewed.map {|u| "#{u.id},"}
but that gives 1,2,3,
What would be a short way to just get something like 1,2,3
an array?
from http://ruby-doc.org/core/classes/Array.html
array.join(sep=$,) → str
Returns a string created by converting each element of the array to a string, separated by sep.
[ "a", "b", "c" ].join #=> "abc"
[ "a", "b", "c" ].join("-") #=> "a-b-c"
users_allowed_to_be_viewed.map{|u| u.id}.join(",")
users_allowed_to_be_viewed.map(&:id).join(',')
Array#join is also aliased to Array#*, although that might make things a little obtuse:
users_allowed_to_be_viewed.map(&:id) * ','
users_allowed_to_be_viewed.join ','
ruby-1.8.7-p299 > users_allowed_to_be_viewed = [1,2,3]
=> [1, 2, 3]
ruby-1.8.7-p299 > users_allowed_to_be_viewed.join ','
=> "1,2,3"

Resources