Looping Through two or more intance vars in Rails - ruby-on-rails

In my view I have two instance variables (going to be more) that I want to display in one table. The first, #data, is an instance var of a model, someting like #data=RnFile.all.
The second is an array #result containing a value per data in #data calculated in the controller. Now in my view I want to display them next to each other, something like:
#data[0].atributes #result[0]
#data[1].atributes #result[1]
#data[2].atributes #result[2]
#data[3].atributes #result[3]
...
but I can't figure out how to iterate over both the arrays (and propably more to come).
Any suggestions anyone? Thanks

You can use Array#zip to do what you want:
#data.zip(#results).each do |data, result|
# use data and result as you need here
end

Related

update_attributes inside each rails

I have array of data
array = [1,2,4,6]
and what i want it update my model like this
array.each do |a|
Mymodel.all.each do |mm|
mm.update_attributes(name: a)
end
end
but problem is when im trying to do this
update_attributes only with last a
at the end all objects have name 6
How can fix it?
because thats what you are doing, you are running each loop over the array but you are doing the same.
first iteration:
Mymodel.all.each do |mm|
mm.update_attributes(name: 1)
end
second iteration:
Mymodel.all.each do |mm|
mm.update_attributes(name: 2)
end
last iteration:
Mymodel.all.each do |mm|
mm.update_attributes(name: 6)
end
so you just update every time the attribute name to the element in the array. and the last one is there to keep.
your logic is incorrect.
That's logical. For every element in the array you're updating all the model records. So first you're updating all your model entries with the first value in your array, being 1, then you're doing the same for very every model entry only with the value 2. Last value in your array is 6 so you're setting all the values in your model to name with the value 6.
I'm not sure what you're trying to accomplish but from your question I assume you want to update your model in order of your array. So something like this.
model_entries = Mymodel.all
array.each do |value, index|
model_entries[index].update_attributes(name: value)
end
That's one solution, but it seems to me that's something wrong with your base logic here. From where I stand this is certainly something you want to solve in a different way. I can't really go into detail here as I don't know enough about what it is you're trying to achieve

access values from multidimen array in ruby

Hi I have an array that i created using push like this
arr.push(h, s.power)
PS: h and s.power both are variables but depends on condition I applied
which ends up something like this
[22,"0.014",22,"0.01",22,"0.01",22,"0.082",22,"0.0002",22,"0.02822",22,"0.0042822",22,"0.041662",21,"0.0042822",21,"0.11107"]
but now I want to create new array for each new value like 22, 21 but I can not access it with many combinations I tried such as arr[22], with arr.map
You should consider using a Hash instead. See ruby hash documentation here.
So instead of pushing h and s.power into an array, you would add them to the hash like this:
my_hash[h] ||= []
my_hash[h].push(s.power)
The first line makes sure you have an array in the hash for the latest value of h. The second adds s.power to that array.
If you run this code repeatedly, you will end up with one array for each unique value of h which you can access like this:
my_hash[22] # <= returns the array of s.power values for h=22
my_hash[21] # <= returns the array of s.power values for h=21
If I understand your question correctly, this should be a clean way to do what you want.

rails each loop with from to

In my controller i fetch 9 row's for object organizations.
#organizations = Organization.where(parent_id: 1).order(city_id: :asc, is_vip: :desc, title: :asc).limit(25).sample(9)
and then in view i must separate this 9 value's to 3 view loops, like first .each do if for row's 1-3, second for 4-6, third 6-9
and i try so:
- #organizations[0..2].each do |org|
...
- #organizations[3..5].each do |org|
...
- #organizations[6..8].each do |org|
...
but it seems that i do something wrong, but what exactly? and how to do it right?
Not sure why your data is duplicated. But you can use the following method for splitting the array into slices
you can use each_slice
#organization.each_slice(3) do |sliced_orgs|
end
Some documentation here
First I don't really get why you use .limit(25).sample(9), you could limit your results to 9 already. But maybe you have some use of the random factor introduced by sample? Strange.
Other than that,
#organizations[0..2].each do |org|
puts org
end
...
should work perfectly fine. If the data is repeated it is because you have multiple times the same entry in your model. sample(9) is taking random unique entries and #organizations[0..2] is a fixed range returning an array or nil. (Rubydoc : ary[range] → new_ary or nil)
In short, nothing wrong with the code but probably somewhere in your data/logic.

get first value in hash within hash

Is there a simple way, instead of looping my entire array to fetch the first value of every inner array.
so in essence I have the following;
array = [['test', 'test2'...], ['test' ....]]
so I want to grab array[#][0] and store the unqiue values.
EDIT
Is there a similar way to use the transpose method for arrays with Hash?
I essentially want to do the same thing
Hash = {1=> {1=> 'test', .....}, 2=> {1=> 'test',....}
so at the end I want to have something like new hash variable and leave my existing hash within hash alone.... = {1 => 'test', 2=> 'test2'}
Not sure if I fully understand the question, but if you have a 2 dimensional array (array in array), and you want to turn that into an array of the first element of the second dimension, you can use the map function
firsts = array.map {|array2| array2.first}
The way map works is that it turns one collection into a second collection by applying a function you provide (the block) to each element.
Maybe this?
array.transpose[0]

How do I collect and combine multiple arrays for calculation?

I am collecting the values for a specific column from a named_scope as follows:
a = survey_job.survey_responses.collect(&:base_pay)
This gives me a numeric array for example (1,2,3,4,5). I can then pass this array into various functions I have created to retrieve the mean, median, standard deviation of the number set. This all works fine however I now need to start combining multiple columns of data to carry out the same types of calculation.
I need to collect the details of perhaps three fields as follows:
survey_job.survey_responses.collect(&:base_pay)
survey_job.survey_responses.collect(&:bonus_pay)
survey_job.survey_responses.collect(&:overtime_pay)
This will give me 3 arrays. I then need to combine these into a single array by adding each of the matching values together - i.e. add the first result from each array, the second result from each array and so on so I have an array of the totals.
How do I create a method which will collect all of this data together and how do I call it from the view template?
Really appreciate any help on this one...
Thanks
Simon
s = survey_job.survey_responses
pay = s.collect(&:base_pay).zip(s.collect(&:bonus_pay), s.collect(&:overtime_pay))
pay.map{|i| i.compact.inject(&:+) }
Do that, but with meaningful variable names and I think it will work.
Define a normal method in app/helpers/_helper.rb and it will work in the view
Edit: now it works if they contain nil or are of different sizes (as long as the longest array is the one on which zip is called.
Here's a method that will combine an arbitrary number of arrays by taking the sum at each index. It'll allow each array to be of different length, too.
def combine(*arrays)
# Get the length of the largest array, that'll be the number of iterations needed
maxlen = arrays.map(&:length).max
out = []
maxlen.times do |i|
# Push the sum of all array elements at a given index to the result array
out.push( arrays.map{|a| a[i]}.inject(0) { |memo, value| memo += value.to_i } )
end
out
end
Then, in the controller, you could do
base_pay = survey_job.survey_responses.collect(&:base_pay)
bonus_pay = survey_job.survey_responses.collect(&:bonus_pay)
overtime_pay = survey_job.survey_responses.collect(&:overtime_pay)
#total_pay = combine(base_pay, bonus_pay, overtime_pay)
And then refer to #total_pay as needed in your view.

Resources