User must enter the array as input. Hash has to accept the input array elements as values.
Create a Ruby program for this by using loops. If array completed print this statement “All array elements are assigned to keys in the hash”
A = [1, 6, 4, 5]
H = {“k1” => 1
“k2” => 6
“k3” => 4
“k4” => 5}
Another solution can be,
a.each_with_index.inject({}) { |m,(a,i)| m["k#{i+1}"] = a; m }
Update: answering to your question
puts 'Enter number of hash elements'
n = gets.to_i
n.times |i|
hash["k#{i+1}"] = gets.to_i
end
puts 'All array elements are assigned to keys in the hash'
A = [1, 6, 4, 5]
Hash[[*'k1'.."k#{A.length}"].zip(A)]
Related
I'm having this type of search:
values = ModelName.find(:all, :conditions => ['attr_id IN (SELECT attr_id FROM srv_type_attr WHERE id IN (?))', serv_objt_attr.collect(&:stya_id)])
Witch returns me an array of needed values:
[33458, 33438]
Next i need to check if record exists with select:
serv_objt_attr.select {|array| array.stya_id == values.collect(&:attr_id).uniq}
This is an example what i'm thinking off.
So how to do it with select, so he would walk through all values witch i'm getting from values.
I know that i could to something like
values.collect(&:attr_id).uniq do |val|
serv_objt_attr.select {|array| array.stya_id == val}
end
But i do not thing that this is a good option.
Ruby 1.8.7
Rails 2.3.4
This is a good case for the set intersection operator:
values = ModelName.find(:all, :conditions => ['attr_id IN (SELECT attr_id FROM srv_type_attr WHERE id IN (?))', serv_objt_attr.collect(&:stya_id)])
values & Set.new(serv_objt_attr.map(&:stya_id)
Here's what the & does:
>> values = [1,2,3]
=> [1, 2, 3]
>> other_array = [1,5,9,3]
=> [1, 5, 9, 3]
>> values & other_array
=> [1, 3]
Let's say you have something like this:
my_array = ['some_rather', 'long_named', 'array_element', 'entry']
I want to remove arbitrary entries by index from my_array without changing it and I want the filtered (i.e. array with indices removed) to be returned from my call. Furthermore, I want to avoid chaining 4 separate calls and write a block doing so.
Example:
filtered_array = my_array.drop_indices(1,3)
You could chain Enumerable's with_index onto Array's reject method to do what you want, though this might violate your desire to not chain separate method calls or write a block to do this:
my_array = ['some_rather', 'long_named', 'array_element', 'entry', 'long_named']
indices_to_remove = [1, 3]
filtered = my_array.reject.with_index { |_, index| indices_to_remove.include?(index) }
p filtered # => ["some_rather", "array_element", "long_named"]
p my_array # => ["some_rather", "long_named", "array_element", "entry", "long_named"]
If this isn't acceptable, the only other thing I can think of right now, to keep duplicate items (as noted in my comment to your solution), is to change from indices_to_remove to indices_to_keep:
my_array = ['some_rather', 'long_named', 'array_element', 'entry', 'long_named']
indices_to_remove = [1, 3]
indices_to_keep = [*(0...my_array.length)] - indices_to_remove
filtered = my_array.values_at(*indices_to_keep)
p filtered # => ["some_rather", "array_element", "long_named"]
p my_array # => ["some_rather", "long_named", "array_element", "entry", "long_named"]
For Arrays with duplicate Elements the best I know is:
array = [0,15,8,15,8]
indices_to_remove = [1,4]
res = array.reject.with_index{ |_,i| indices_to_remove.include?(i) }
returns
[0,8,15]
Additionally for arrays with unique entries such as a set of users
(using variable definitions from the question)
filtered_array = my_array - my_array.values_at(1,3)
Bonus, if your indices are inside an array themselves:
indices_to_remove = [1,3]
filtered_array = my_array - my_array.values_at(*indices_to_remove)
I think this is rather descriptive, not awkward and not shorter than needed.
One more possible solution with some addition, now it's also will work with negative indexes:
array = %w( a b c d e f )
indexes = [1, 2, -1, -9, -6, 6]
def array_except(array, *indexes)
indexes = indexes.map { |e| e.negative? ? e + array.length : e }
array.values_at(*((0...array.length).to_a - indexes))
end
array_except(array, *indexes)
=> ["d", "e"]
array_except(array, 0, -1)
=> ["b", "c", "d", "e"]
I have an array [5,2,6,4] and I would like to create a structure such as the first minus the second etc until the last row.
I have tried using map, but not sure how to proceed since i might need indxes.
I would like to store the result in something that looks like:
{1 => (5, 2, 3), 2 =>(2,6,-4), 3 => (6,4,2)}
So an array of x should return x-1 hashes.
Anybody knows how to do? should be a simple one.
Thank you.
First, you want to work with the array elements in pairs: 5,2, 2,6, ... That means you want to use each_cons:
a.each_cons(2) { |(e1, e2)| ... }
Then you'll want the index to get the 1, 2, ... hash keys; that suggests throwing a Enumerator#with_index into the mix:
a.each_cons(2).with_index { |(e1, e2), i| ... }
Then you can use with_object to get the final piece (the hash) into play:
a.each_cons(2).with_index.with_object({}) { |((e1, e2), i), h| h[i + 1] = [e1, e2, e1 - e2] }
If you think all the parentheses in the block's arguments are too noisy then you can do it in steps rather than a single one-liner.
You can use each_index:
a = [5, 2, 6, 4]
h = {}
a[0..-2].each_index { |i| h[i+1] = [a[i], a[i+1], a[i] - a[i+1]] }
h
=> {1=>[5, 2, 3], 2=>[2, 6, -4], 3=>[6, 4, 2]}
Try to use
each_with_index
Suppose you have an array:
arr = [3,[2,3],4,5]
And you want to covert with hash(key-value pair). 'Key' denotes an index of an array and 'value' denotes value of an array. Take a blank hash and iterate with each_with_index and pushed into the hash and finally print the hash.
Try this:
hash={}
arr.each_with_index do |val, index|
hash[index]=val
end
p hash
Its output will be:
{0=>3, 1=>[2, 3], 2=>4, 3=>5}
If you want that index always starts with 1 or 2 etc then use
arr.each.with_index(1) do |val, index|
hash[index] = val
end
Output will be:
{1=>3, 2=>[2, 3], 3=>4, 4=>5}
Ok so I have an array of 'winner ids' this array represents users who have won in the previous round of a tournament. I then have an array of objects called 'tournament participations', this represents all the users that have participated in the tournament (many to many relationship join table).
For each 'winner id' I want to iterate through the 'tournament participations' array and find the tournament participation with a user_id that matches the 'winner id', then push it into a new array called 'round participations'...
I have tried the code below but I always get returned the original 'winner_ids' array....
#challenges = Challenge.where(tournament_id: #tournament.id)
#winner_ids = #challenges.pluck(:winner_id)
#tournament_participations = #tournament.tournament_participations
#round_participations = []
#round_participations = #winner_ids.each do |winner_id|
#round_participation = #tournament_participations.where(user_id: winner_id)
#round_participations << #round_participation
end
each returns the enumerable it was called on; in this case, #winner_ids.each is returning #winner.ids. You don't need to assign the result of the iteration to #round_participations.
Also, check out the map method.
Use the map method, instead of .each.
The map method can be used to create a new array based on the original array, but with the values modified by the supplied block. See the below example.
In case of each method
irb(main):001:0> arr = [1, 2, 3, 4, 5]
=> [1, 2, 3, 4, 5]
irb(main):002:0> arr.each { |a| print a -= 10, " " }
-9 -8 -7 -6 -5
=> [1, 2, 3, 4, 5]
you can see after iterations it returned the original array. But in the case of map
irb(main):005:0> arr = [1, 2, 3, 4, 5]
=> [1, 2, 3, 4, 5]
irb(main):006:0> arr.map { |a| 2*a }
=> [2, 4, 6, 8, 10]
map can transform the contents of an array, meaning that it can perform an operation on each element in the array.
I have a hash, its values are 2 dimensional arrays, e.g.
hash = {
"first" => [[1,2,3],[4,5,6]],
"second" => [[7,88,9],[6,2,6]]
}
I want to access the elements to print them in xls file.
I did it in this way:
hash.each do |key, value|
value.each do |arr1|
arr1.each do |arr2|
arr2.each do |arr3|
sheet1.row(row).push arr3
end
end
end
end
Is there a better way to access each single element without using each-statement 4 times?
The desired result is to get each value from key-value pair as an array, e.g.
=> [1,2,3,4,5,6] #first loop
=> [7,88,9,6,2,6] #second loop
#and so on
hash = { "first" =>[[1, 2,3],[4,5,6]],
"second"=>[[7,88,9],[6,2,6]] }
hash.values.map(&:flatten)
#=> [[1, 2, 3, 4, 5, 6], [7, 88, 9, 6, 2, 6]]
Isn't it as simple as something like:
hash.each do |k,v|
sheet1.row(row).concat v.flatten
end