Reduce nested array to string? - ruby

I have the following array:
arr = [["Example"]]
I need to reduce it to just "Example" (basically, just remove the array).
I know I could do arr[0][0], but am curious if there's a simple method to just remove the string from the array without using indexes.
For clarification...there will only ever be a single item in the array.

For a single item, you can use:
[['array']].join
=> 'array'
Updated with more examples
If you have multiple items, the strings will be combined:
[['array'], ['array']].join
=> 'arrayarray'
And if you pass a parameter to the join method:
[['array'], ['array']].join('&')
=> 'array&array'

While this is not as efficient as [0][0], it will still work:
arr.flatten.first

Related

Better way to loop through a set of hashes assigning array values in Ruby

I am trying to insert data into Postgres. I have an array of data and I am trying to assign each column a value of the array. Here is an example.
pg_insert = ['12/09/2015', 41, 'test account', '41.0']
Table.create([date: pg_insert[0],
account_number: pg_insert[1],
account_name: pg_insert[2],
values: pg_insert[3]])
Is there a way where I can loop this so I can put i in pg_insert instead of having to type out numbers? I'm not sure how to loop inside of the create() parameter. Is there any way around this?
Any suggestions would be great thanks.
Table.create is accepting a Hash, I'm sure.
So here is what you can do:
Make an Array called keys that contains 4 symbols :date, :account_number, :account_name, and :values.
pg_insert is already an Array.
Now you can put the two Arrays together to make the Hash you need: Hash[keys.zip(pg_insert)]
This allows you to call Table.create like this: Table.create(Hash[keys.zip(pg_insert)])
Here is the finished code then:
keys = [:date, :account_number, :account_name, :values]
pg_insert = ['12/09/2015', 41, 'test account', '41.0']
Table.create(Hash[keys.zip(pg_insert)]) # or Table.create Hash[keys.zip(pg_insert)] if you don't want so many parentheses.
Note that pg_insert will always have to be in the same order as keys.
You can read more about Array#zip and Hash.new to understand how those work. This SO link might also be helpful: Converting an array of keys and an array of values into a hash in Ruby

Delete a string in an array when it exist in another array

In a ruby-script I have two arrays
exclude = ['bgb400', 'pip900', 'rtr222']
result = ['pda600', 'xda700', 'wdw300', 'bgb400', 'ztz800', 'lkl100']
I want to iterate over the result array and remove any string that exists in the exclude array. In the end the string 'bgb400' should be removed from the result array.
Use operator -
irb(main):004:0> result - exclude
=> ["pda600", "xda700", "wdw300", "ztz800", "lkl100"]
If you really need to modify your result array you can use reject!. However if it is the case, you better review your code.
result.reject! {|s| exclude.include? s}
simply do:
new_result = result - exclude
=> ["pda600", "xda700", "wdw300", "ztz800", "lkl100"]
actually what it does is check for matching entries in both arrays and produce the result excluding the matching entries.
It sounds like Array#delete_if method is best for this task.
exclude = ['bgb400', 'pip900', 'rtr222']
result = ['pda600', 'xda700', 'wdw300', 'bgb400', 'ztz800', 'lkl100']
In order to remove elements in the reuslt array that are included in the excude array try this
result.delete_if{|r|exclude.include?('r')}

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

Merge hash with array values to one array

How to merge hash with array values to one array:
h = {
one: ["one1", "one2"],
two: ["two1", "two2"]
}
after merge should be:
["one1","one2","two1","two2"]
h.values.flatten
# => ["one1", "one2", "two1", "two2"]
You can do the same for the keys, of course. The only reason you need flatten here is because the values are themselves arrays, so h.values alone will return [["one1", "one2"], ["two1", "two2"]].
Also, just as an FYI, merge means something different (and pretty useful) in Ruby.
If you want to make sure it flattens only one level (per #tokland's comment), you can provide an optional argument to flatten such as with flatten(1).
h.flat_map &:last
=> ["one1", "one2", "two1", "two2"]

Populating array (by 'name') in array of arrays

Lets say i have an array of arrays, of which i dont know the names, just that they are arrays, and how many of them there are.
bigArray=[smallArrayA[], smallArrayB[]]
Now i can fetch the array(s) by indexposition, like:
smallA = bigArray[0]
smallA << 'input'
But what i'd like to know is the names of the arrays, stored in the 'big' one..
bigArray.inspect
..just gives me:
[['input'],[]]
My problem is that the names of the smaller ones are going to be created dynamiclly, and i need to know their names to modify the right one, later on.
Sounds like you need a hash:
bigHash = { :a => smallArrayA, :b => smallArrayB }
Now you can refer to each element of the hash by name:
bigHash[:a]

Resources