Ruby difference between statements [closed] - ruby

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I'm using Solr to search for a list of companies. when I try to filter
Works
companies = []
current_user.cached_company.cached_companies.each do |company|
companies << company.id
end
Doesn't Work
companies = []
companies << current_user.cached_company.cached_companies.map(&:id)
When I call
#search = Company.search do
with :id, companies
end
#companies = #search
It works with the first example but not the second.
However, this works just fine
#search = Company.search do
with :id, current_user.cached_company.cached_companies.map(&:id)
end
#companies = #search
I know that I'm missing something simple here. I know it doesn't have to do with the caching, but cannot wrap my head around what's going on.

Your second example is putting a nested array in companies. Here's a simplified idea of what's going on:
data = [{value: 1}, {value: 2}, {value: 3}]
foo = []
data.each do |number|
foo << number[:value]
end
p foo
# => [1,2,3] # One array with 3 values
foo = []
foo << data.map { |item| item[:value] }
p foo
# => [[1,2,3]] # One array with one value (another array with 3 values)
Either stick with your first version, or just do this:
companies = current_user.cached_company.cached_companies.map(&:id)
Or, if you want to stick with your 2nd version, make sure to flatten the values before you use them:
companies.flatten!

Related

How do I iterate over this Hash in Ruby? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed last year.
Improve this question
[:sha,"string"]
[:node_id,"dsd"]
[:stats,{:total=>122},:additions=>23],:deletions=>72}]
[:files,[{:sha=>"456"},:filename=>"456"],{:sha=>"123"},:filename=>"123"]]
I want to access the content of files sha and stats.
client.commit("healtheintent/hcc_reference_service","3a3c56babbc1c77323d178303fa06f8d11e1133d").each do |key,value|
if("#{key}"=="files")
puts ("#{value}")
end
end
Now the values returns the entire content inside the files
Similarily, How do I access the stats
How to iterate over the hash in general
hash = { a: 1, b: 2, c: 2 }
hash.each do |key, value|
if key == :a
puts "a is #{value}"
else
puts "It is not a, it's #{key}"
end
end
Also you can iterate over the keys only or over the values only using each_key or each_value methods

I need my API to print a list of titles as well as a full description. I am having trouble getting a list of titles. Any advice? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
class RecipePuppyAPI1
URL = "http://www.recipepuppy.com/api/"
def get_recipes
uri = URI.parse(URL)
response = Net::HTTP.get_response(uri)
JSON.parse(response.body)
end
def recipe_titles(json)
recipes = []
json.collect do |recipe|
recipes << recipe["title"]
end
end
end
recipes = RecipePuppyAPI1.new.get_recipes
puts ap recipes.uniq
Your recipe_titles method doesn't return the right thing. collect is used to map 1:1 an input array to an output array, and the output of each iteration is the result.
It looks like you're confusing each, an iterator, with collect, which is a transform operation. You're also declaring an array which isn't used properly, as normally that'd be your return value.
To fix it, remove the temporary variable, strip it down to this:
def recipe_titles(json)
json.collect do |recipe|
recipe["title"]
end
end
Or more generically:
def recipe_fields(json, field)
json.collect do |recipe|
recipe[field]
end
end
Where you can call it like:
recipe_fields(json, 'title')

updating array based on symbols Ruby [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
How does one update the array based on symbols? Like
data = []
string = "Hello"
if( !data.include? string )
count += 1
data.insert(-1, {
label: string,
value: count,
})
else
#logic to change count value if string is encountered again
end
I was thinking of finding the index where the string lies and then delete that to insert another updated values at that index. Is this the right approach?
Just use find to get the match, provided its the only one in the array. You can use select to get multiple matches. After that just update the count
As your example is taken out of context and contains errors, I've taken a liberty to make a more complete example.
data = []
strings = ["Hello", "Bye", "Hello", "Hi"]
strings.each do |string|
hash = data.find{ |h| h[:label] == string }
if hash.nil?
data << {label: string, value: 1}
else
hash[:value] += 1
end
end

What is the correct way to use variable symbols in a hash? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 8 years ago.
Improve this question
I have two arrays:
people_keys = ['id', 'name', 'email']
people_values = [[1, 'Tarzan', 'tarzan#jungle.com'],
[2, 'Jane', 'jane#jungle.com' ]]
and I want to make an array of people:
people = []
people_values.each do |person_values|
person = {}
person_values.each_with_index do |person_value, index|
person[people_keys[index]] = person_value
end
people.push( person )
end
This gives me the following result:
people # => [{"id"=>1, "name"=>"Tarzan", "email"=>"tarzan#jungle.com"},
# {"id"=>2, "name"=>"Jane", "email"=>"jane#jungle.com" }]
I want to make id, name and email symbols instead of strings,
so I came up with the following:
I replaced
person[people_keys[index]] = person_value
with
person[:"#{people_keys[index]}"] = person_value
This gives me the following result:
people # => [{:id=>1, :name=>"Tarzan", :email=>"tarzan#jungle.com"},
# {:id=>2, :name=>"Jane", :email=>"jane#jungle.com" }]
This works just fine but seems like it could be done better/cleaner,
but I am unable to find a better solution.
I'd like to know if there is in fact a better solution for this problem.
Ruby's String class has a to_sym method:
Returns the Symbol corresponding to str, creating the symbol if it did not previously exist.
You could do something like this:
people_values.map { |person| people_keys.map(&:to_sym).zip(person).to_h }

Load functions with all variable names. Is there another way? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
Is there a better way to do this?
value = 10
train = []
storage = 12
another_var = 'apple'
def first_function(value, train, storage, another_var)
second_function(train, storage)
third_function(train, storage, another_var)
forth_function(value, another_var)
end
def third_function(train, storage, another_var)
puts 'x'
end
def second_function(train, storage)
puts 'x'
end
def forth_function(value, another_var)
puts 'x'
end
Is this the proper way to do this? Taking the values along for the ride? I'm working my way through LRTHW and I'm trying to build a game. The problem I am running into is that I have a for loop that represents turns and that acts as the game driver. Inside of that for loop it calls functions that then call more functions. Unless I load all the variables into the first function and then pass them down the chain it breaks. It's sort of neat that it blocks you from accessing variables outside of the very narrow scope, but is there a way I can override this?
You may want to use instance variables to keep them in scope without having to pass them as parameters every time.
#value = 10
#train = []
#storage = 12
#another_var = 'apple'
def first_function
second_function
third_function
fourth_function
end
def third_function
puts #another_var
end
def second_function
puts #value + #storage
end
def fourth_function
puts #train
end
I believe what you want is to be able to do all combinations of optional parameters.
Try this:
def myfunction(options={})
options = {:value => 10, :train => [], :storage => 12, :another_var => 'apple'}.merge(options)
puts options[:value]
puts options[:train]
puts options[:storage]
puts options[:another_var]
end
Example usage:
irb(main):013:0> myfunction({})
10
12
apple
=> nil
irb(main):014:0> myfunction({:value => 11, :storage => 23})
11
23
apple
=> nil

Resources