Why am I geting wrong results in my array with I iterate? - ruby

I am iterating on a array within a Object van. I am trying to pop the elements of the array into another object array. See below.
#van.bikes.each { #garage<<( #van.removebike )}
def removebike
#bikes.pop
end
When I do this the resulting array in the garage has missing elements and/or duplicate elements.

The reason for this is that when ruby iterates on the array it sets number of iterations based on the original array size. When you pop an element from that array the size changes so the iteration can not work properly.
You can use instead,
#van.bikes.count.times { #garage<<( #van.removebike )}

You can try this too..
#garage = []
#van.bikes.each{|bike| #garage << bike}

Related

How to sort an array in Ruby

Persoane = []
Nume = gets
Persoane.push Nume.split(",")
puts Persoane.sort
I am trying to get an user to input carachters that get split into substrings which get inserted in an array, then the program would output the strings in alphabetical order. It doesnt seem to work and I just get the array's contents, like so:
PS C:\Users\Lenovo\Desktop\Ruby> ruby "c:\Users\Lenovo\Desktop\Ruby\ruby-test.rb"
Scrie numele la persoane
Andrei,Codrin,Bradea
Andrei
Codrin
Bradea
PS C:\Users\Lenovo\Desktop\Ruby>
you can do this :
Nume = gets
puts Nume.split(",").sort
or in 1 line
array = gets.chomp.split(",").sort
The error is because of your use of push. Let's assume that you define the constant Nume by
Nume='Andrei,Codrin,Bradea'
Then, Nume.split(',') would return the Array ['Andrei', 'Codrin', 'Bradea']. When you do a Persoane.push, the whole array is added to your array Persoane as a single element. Therefore, Persoane contains only one Element, as you can verify when you do a
p Persoane
If you sort a one-element array, the result will also be just that one element - there is nothing to sort.
What you can do is using concat instead of push. This would result in Persoane being a 3-element array which can be sorted.
I'm not sure you need use constants here
If you don't need keep user input and use it somewhere, you can just chain methods like this
persons = gets.chomp.split(",").sort
For something a little different, let's not split at all.
people = gets.scan(/[^,]+/).map(&:strip).sort
This will avoid problems like multiple commas in a row yielding empty strings. Of course, you could also avoid that with:
people = gets.split(/\,+/).map(&:strip).sort

In Ruby is there a way to get the index of an item in an array that consists of structs?

With a normal array, I can use the arrayname.find_index('whatimlookingfor') to get the position within the array.
I can't figure out how to do this when the elements of the array are Struct's.
Scenario: I have a struct that consists of an ID and the Filename. In one function I need to find within that array the ID of a different file than the one I'm currently processing. I know the other filename, so what I was hoping that I could do something like:
arrayname.filename.find_index(parsedfilename)
But this obviously fails. Without iterating through the entire array is there a way to quickly reference the index of where the match happens? Or am I out of luck because the array is a collection of structs?
index (same as find_index) takes a block in which you can code up any true/false logic for your finder. To find the index of the first item whose filename does not match parsedfilename...
found_index = items.index { |item| item.filename != parsedfilename }
Many methods which work with Arrays and Enumerables also take blocks.

How to count the elements of an array inside an array?

I have a method which returns the number of hotels from a webpage:
hotel_count = self.getHotelsList.values
The output of this method is:
[["hotel_0", "hotel_1", "hotel_2", "hotel_3", "hotel_4", "hotel_5", "hotel_6", "hotel_7", "hotel_8", "hotel_9", "hotel_10", "hotel_11", "hotel_12", "hotel_13", "hotel_14", "hotel_15", "hotel_16", "hotel_17", "hotel_18", "hotel_19", "hotel_20", "hotel_21", "hotel_22", "hotel_23", "hotel_24", "hotel_25", "hotel_26", "hotel_27", "hotel_28", "hotel_29", "hotel_30", "hotel_31", "hotel_32", "hotel_33", "hotel_34", "hotel_35", "hotel_36", "hotel_37", "hotel_38", "hotel_39", "hotel_40"]]
I want to know the length of this array, but if I write
hotel_count = self.getHotelsList.values.length
The length is 1. How can I get a length of 41, which is the one I'm expecting?
Thanks
The array you are showing is nested inside another array. So the outer array is of length 1, the inner array is what you want.
To get it you have to first get the first element of the outer array using [0] or first
testList[0].length
testList.first.length
I am not sure why your getHotelsList method returns a nested array, it doesn't appear to need it.
hotel_count = getHotelsList.values.first.length
You can also do it with [0], but first is faster.
Two notes:
You don't need self at the beginning.
It is a bad habit to use camel case for method names in Ruby. it should better be get_hotels_list.
You could convert that into a single array with flatten:
hotel_count = self.getHotelsList.values.flatten.size

ruby collect unique elements

I have some array of hashes
a = [{name:"x", long:1.0, lat:2.0},
{name:"y", long:2.0, lat:3.0},
{name:"z", long:1.0, lat:2.0}]
how to delete {name:"x", long:1.0, lat:2.0}, which coords are equal of last element, Other words I need to leave last (in my case: with name:"z") hash with unique coords and drop all previous element with same coords
Try using Array#uniq with a block:
a.uniq { |item| [item[:lat], item[:long]] }
The return value of the block is used as the value to compare for uniqueness.
It's not clear why you want "x" to be deleted and not "z", but you could achieve that with the example data set by reversing the array before calling uniq on it.

Add all Arrays with an Main Array without duplicates

I need to add an array of array in to a single array without duplicates
array = [[1,2,3],[2,3,4],[7,8,9]]
to
new_array [1,2,3,4,7,8,9]
What is the best possible way to do IT in Ruby.
Try this:
array.flatten!.uniq!
flatten! takes any sub-arrays and adds their elements to the enclosing array (recursively), so it "flattens out" arrays of arrays.
uniq! removes duplicate elements from the array.
Note that ! methods modify the original array. Use the non-! methods (flatten and uniq) if you wish to return a new array instead.

Resources