How to print last elements of array - ruby

how do I print all elements of an array after the second element ex:
ARR=["a","b","c","d","f"]
I want to print c d f
ARR=["cat","dog","horse"]
I want to print horse
Thanks in advance

Just as easy as
p ARR[2..-1]
where 2 and -1 are indexes of an elements.

Use Array#[] with range or Array#drop
arr = ["a","b","c","d","f"]
arr[2..-1]
# => ["c", "d", "f"]
arr.drop(2)
# => ["c", "d", "f"]
arr = ["cat","dog","horse"]
arr[2..-1]
# => ["horse"]
arr.drop(2)
# => ["horse"]

Use Array#last method
arr.last(arr.size - 2)

Related

How can I find the missing letter in an array

Given an array of letters arr = ["a","b","c","d","f"], I would like to construct an array containing all letters between the smallest and largest letters (by ASCII value) in arr that are not contained in arr. Here that would be ["e"]. How can I to that?
a = %w[a b c d f]
(a.min..a.max).to_a - a # => ["e"]
Assuming that the letters in the array are within "a" to "z" and ordered alphabetically, you could fetch the array's first and last element:
given_letters = ["a", "b", "c", "d", "f"]
first_letter = given_letters.first #=> "a"
last_letter = given_letters.last #=> "f"
and call String#upto and Enumerable#to_a to retrieve an array of all successive letters:
all_letters = first_letter.upto(last_letter).to_a
#=> ["a", "b", "c", "d", "e", "f"]
which can be used to calculate the difference to the original array via Array#-:
all_letters - given_letters
#=> ["e"]
Let
ascii = arr.uniq.map(&:ord)
#=> [97, 98, 99, 100, 102]
sm, lg = ascii.minmax
#=> [97, 102]
If it is known that there is exactly one letter e for which sm < e.ord < lg and e is not an element of arr, we can write the following.
((sm+lg)*(lg-sm+1)/2 - ascii.sum).chr
#=> (597 - 496).chr => 101.chr => "e"
That is because sm..lg represents an arithmetic progression; hence, the sum of its elements equals
(sm+lg)*(lg-sm+1)/2
#=> 597

Create an array from a hash with each_with_index

I have an array:
arr = ["a", "b", "c"]
What I want to do is to create a Hash so that it looks like:
{1 => "a", 2 => "b", 3 => c}
I tried to do that:
Hash[arr.each_with_index.map { |item, i| [i => item] }]
but didn't get what I was looking for.
each_with_index returns the original receiver. In order to get something different from the original receiver, map is necessary anyway. So there is no need of an extra step using each or each_with_index. Also, with_index optionally takes the initial index.
Hash[arr.map.with_index(1){|item, i| [i, item]}]
# => {1 => "a", 2 => "b", 3 => c}
Hash[] takes an array of arrays as argument. So you need to use [i, item] instead of [i => item]
arr = ["a", "b", "c"]
Hash[arr.each_with_index.map{|item, i| [i+1, item] }]
#=> {1=>"a", 2=>"b", 3=>"c"}
Just for clarification: [i => item] is the same as writing [{i => item}] so you really produced an array of arrays that in turn contained a single hash each.
I also added a +1 to the index so the hash keys start at 1 as you requested. If you don't care or if you want to start at 0, just leave that off.
arr = ["a", "b", "c"]
p Hash[arr.map.with_index(1){|i,j| [j,i]}]
# >> {1=>"a", 2=>"b", 3=>"c"}

Get a fixed size slice from array

I need to dynamically retrieve a slice of size 3 from an array (as part of a more complex method):
a = %w(a b c d e)
i = 0 # i is an argument, I need [nil, "a", "b"]
a[(i-1)..(i+1)]
=> [] # no luck
a[(i-1), 3]
=> ["e"]
I know that when code gets messed up, it's not ruby's fault, is mine. What I'm missing? Is there a better way to achieve this?
I need to clarify. What I want is a slice of a given size, around a given index, and maping to nil if the slice goes beyond offset.
Here's a compact way you can do this. It relies on the fact that indexing beyond an array returns nil.
>> i = 0; 3.times.map{|j| a[j+i]}
=> ["a", "b", "c"]
>> i = 4; 3.times.map{|j| a[j+i]}
=> ["e", nil, nil]
Is each_slice the method you are looking for? Otherwise try to provide a better example for what you actually want to achieve.
Enumerable#each_cons will do the trick:
a.each_cons(3){|slice| p slice }
output:
["a", "b", "c"]
["b", "c", "d"]
["c", "d", "e"]
This is how I made it (having to go around ruby indexing negative values):
a = %w(a b c d e)
def slice_around(ary, index)
slice_3 = ->(x){ x == 0 ? [ary.size+1,0,1] : ((x-1)..(x+1)).to_a }
idxs = slice_3.call(index).map { |i| ary[i] }
end
> slice_around a, 0
=> [nil, "a", "b"]
> slice_around a, 2
=> ["b", "c", "d"]
It wont work if a negative index is passed though.

Reorder Ruby array based on the first element of each nested array

My goal is to convert a into b:
a = [["a","b"], ["d", "c"], ["a", "o"], ["d", "g"], ["c", "a"]]
b = [[["a","b"], ["a", "o"]], ["c", "a"], [["d", "c"], ["d", "g"]]
They are grouped by the first element in each nested array. So far I have:
def letter_frequency(c)
d = Hash.new(0)
c.each do |v|
d[v] += 1
end
d.each do |k, v|
end
end
def separate_arrays(arry)
arry2 = []
arry3 = []
big_arry = []
y = 0
while y < arry.length
arry2.push(arry[y][0])
arry3.push(arry[y][1])
y += 1
end
freq = letter_frequency(arry2)
front = arry.slice!(0..(freq["a"] - 1))
end
separate_arrays(a)
Not only does this seem like overkill, but there are now guarantees that "a" will be a legit Hash key, so the last part doesn't work. Thanks for any help.
You can try to do something like this:
a.group_by(&:first).values.map {|e| e.length > 1 ? e : e.flatten}
# => [[["a", "b"], ["a", "o"]], [["d", "c"], ["d", "g"]], ["c", "a"]]
I use the following methods:
Enumerable#group_by (by first element of an array, like in your question):
Returns a hash, which keys are evaluated result from the block, and
values are arrays of elements in enum corresponding to the key.
Hash#values:
Returns a new array populated with the values from hsh. See also Hash#keys.
Enumerable#map (required because you don't want to get nested array when there are only one match, like for c letter):
Returns a new array with the results of running block once for every element in enum.
Enumerable#flatten:
Returns a new array that is a one-dimensional flattening of this array
(recursively). That is, for every element that is an array, extract
its elements into the new array. If the optional level argument
determines the level of recursion to flatten

hash of Array gives incorrect size results - Ruby

I am trying to insert a List in Hash.. However, hash[key].size is giving me invalid results.
p = Hash.new
p = {"a" => ["b","e"]}
puts p["a"].size #prints 2 ----This is the Problem
p["a"] << ["d", "f"]
puts p["a"].size #prints 3
puts p["a"][1] #prints e
puts p["a"][2] #prints df
How, adding more lists increment the size only by one (which is correct). Is there any way to properly initialize the hash -to not increase the size to 2.
Edited to add: Your comments indicate that you want for element 'a' to be an array of arrays. Here it is:
h = Hash.new
h = {"a" => [["b","e"]]}
p h # => {"a"=>[["b", "e"]]}
h["a"] << ["d", "f"]
p h # => {"a"=>[["b", "e"], ["d", "f"]]}
When diagnosing a problem, prefer p to puts. puts can hide details that are important. Let's add a few calls to p and see what we find out. Oh, and I'll change the name of the hash from "p" to "h". Otherwise there's just too many "p's" around.
h = Hash.new
The above line is unnecessary. The next line assigns an array to "h", overwriting this assignment.
h = {"a" => ["b","e"]}
p h # => {"a"=>["b", "e"]}
p h["a"].size # 2
Everything is exactly as it should be, even h["a"].size returning 2. why?
p h["a"] # => ["b", "e"]
Because h["a"] is an array with two elements.
h["a"] << ["d", "f"]
p h # => {"a"=>["b", "e", ["d", "f"]]}
Do you see what happened? << appends a single element to the end of an array, and that single element is the array ["d", "f"]. And that's why:
p h["a"].size # => 3
Because there are indeed three elements in the array: the strings "b" and "e", and the array ["d", "f"].
If you meant to append the elements "d" and "f" to the array, then do it with +=:
h = {"a" => ["b","e"]}
h["a"] += ["d", "f"]
p h # => {"a"=>["b", "e", "d", "f"]}

Resources