How to get the last element of an array in Ruby? - ruby

Example:
a = [1, 3, 4, 5]
b = [2, 3, 1, 5, 6]
How do I get the last value 5 in array a or last value 6 in array b without using a[3] and b[4]?

Use -1 index (negative indices count backward from the end of the array):
a[-1] # => 5
b[-1] # => 6
or Array#last method:
a.last # => 5
b.last # => 6

One other way, using the splat operator:
*a, last = [1, 3, 4, 5]
a => [1, 3, 4]
last => 5

Related

Move the pointer along an array, n number of times

I want to move through just two indexes of an array. Something along these lines
iterate_amount = 2
array = [2,4,6,7]
iterate_amount.times do |x|
puts x
end #=> 2,4
I just don't know how I can place the 'array' in the loop to tell the interpreter this is the array I want to move through two indexes.
You can use Enumerable#cycle:
array = [2,4,6,7]
array.cycle(2) do |x|
puts x
end
prints
2
4
6
7
2
4
6
7
UPDATE
Use Array#[] with specifying start, length OR with specifying range.
>> array[0, 2]
=> [2, 4]
>> array[0..1]
=> [2, 4]
>> array[0...2]
=> [2, 4]
use Array#take http://ruby-doc.org/core-2.0.0/Array.html#method-i-take
>> a = [2,4,6,7]
=> [2, 4, 6, 7]
>> a.take 2
=> [2, 4]

How to multiply every other element of an array?

Let's say that I have an array like this:
[1,2,3,4,5,6,7]
how can I multiply every other number of this array except the first by 2
so my new array looks like this
[1,4,3,8,5,12,7]
You can use map and with_index:
[1,2,3,4,5,6,7].map.with_index{|v,i| i % 2 == 0 ? v : v * 2 }
# => [1, 4, 3, 8, 5, 12, 7]
[1,2,3,4,5,6,7].each_slice(2).flat_map{|k, l| [k, *(l * 2 if l)]}
# => [1, 4, 3, 8, 5, 12, 7]

delete ONE array element by value in ruby

How can I delete the first element by a value in an array?
arr = [ 1, 1, 2, 2, 3, 3, 4, 5 ]
#something like:
arr.delete_first(3)
#I would like a result like => [ 1, 1, 2, 2, 3, 4, 5]
Thanks in advance
Pass the result of Array#find_index into Array#delete_at:
>> arr.delete_at(arr.find_index(3))
>> arr
=> [1, 1, 2, 2, 3, 4, 5]
find_index() will return the Array index of the first element that matches its argument. delete_at() deletes the element from an Array at the specified index.
To prevent delete_at() raising a TypeError if the index isn't found, you may use a && construct to assign the result of find_index() to a variable and use that variable in delete_at() if it isn't nil. The right side of && won't execute at all if the left side is false or nil.
>> (i = arr.find_index(3)) && arr.delete_at(i)
=> 3
>> (i = arr.find_index(6)) && arr.delete_at(i)
=> nil
>> arr
=> [1, 1, 2, 2, 3, 4, 5]
You can also use :- operator to remove desired element from the array, e.g.:
$> [1, 2, 3, '4', 'foo'] - ['foo']
$> [1, 2, 3, '4']
Hope this helps.

How to drop the end of an array in Ruby

Array#drop removes the first n elements of an array. What is a good way to remove the last m elements of an array? Alternately, what is a good way to keep the middle elements of an array (greater than n, less than m)?
This is exactly what Array#pop is for:
x = [1,2,3]
x.pop(2) # => [2,3]
x # => [1]
You can also use Array#slice method, e.g.:
[1,2,3,4,5,6].slice(1..4) # => [2, 3, 4, 5]
or
a = [1,2,3,4,5,6]
a.take 3 # => [1, 2, 3]
a.first 3 # => [1, 2, 3]
a.first a.size - 1 # to get rid of the last one
The most direct opposite of drop (drop the first n elements) would be take, which keeps the first n elements (there's also take_while which is analogous to drop_while).
Slice allows you to return a subset of the array either by specifying a range or an offset and a length. Array#[] behaves the same when passed a range as an argument or when passed 2 numbers
this will get rid of last n elements:
a = [1,2,3,4,5,6]
n = 4
p a[0, (a.size-n)]
#=> [1, 2]
n = 2
p a[0, (a.size-n)]
#=> [1, 2, 3, 4]
regard "middle" elements:
min, max = 2, 5
p a.select {|v| (min..max).include? v }
#=> [2, 3, 4, 5]
I wanted the return value to be the array without the dropped elements. I found a couple solutions here to be okay:
count = 2
[1, 2, 3, 4, 5].slice 0..-(count + 1) # => [1, 2, 3]
[1, 2, 3, 4, 5].tap { |a| a.pop count } # => [1, 2, 3]
But I found another solution to be more readable if the order of the array isn't important (in my case I was deleting files):
count = 2
[1, 2, 3, 4, 5].reverse.drop count # => [3, 2, 1]
You could tack another .reverse on there if you need to preserve order but I think I prefer the tap solution at that point.
You can achieve the same as Array#pop in a non destructive way, and without needing to know the lenght of the array:
a = [1, 2, 3, 4, 5, 6]
b = a[0..-2]
# => [1, 2, 3, 4, 5]
n = 3 # if we want drop the last n elements
c = a[0..-(n+1)]
# => [1, 2, 3]
Array#delete_at() is the simplest way to delete the last element of an array, as so
arr = [1,2,3,4,5,6]
arr.delete_at(-1)
p arr # => [1,2,3,4,5]
For deleting a segment, or segments, of an array use methods in the other answers.
You can also add some methods
class Array
# Using slice
def cut(n)
slice(0..-n-1)
end
# Using pop
def cut2(n)
dup.tap{|x| x.pop(n)}
end
# Using take
def cut3(n)
length - n >=0 ? take(length - n) : []
end
end
[1,2,3,4,5].cut(2)
=> [1, 2, 3]

How do I check an array for duplicates? [duplicate]

This question already has answers here:
How to find and return a duplicate value in array
(23 answers)
Closed 8 years ago.
I've got an array A. I'd like to check if it contains duplicate values. How would I do so?
Just call uniq on it (which returns a new array without duplicates) and see whether the uniqed array has less elements than the original:
if a.uniq.length == a.length
puts "a does not contain duplicates"
else
puts "a does contain duplicates"
end
Note that the objects in the array need to respond to hash and eql? in a meaningful for uniq to work properly.
In order to find the duplicated elements, I use this approach (with Ruby 1.9.3):
array = [1, 2, 1, 3, 5, 4, 5, 5]
=> [1, 2, 1, 3, 5, 4, 5, 5]
dup = array.select{|element| array.count(element) > 1 }
=> [1, 1, 5, 5, 5]
dup.uniq
=> [1, 5]
If you want to return the duplicates, you can do this:
dups = [1,1,1,2,2,3].group_by{|e| e}.keep_if{|_, e| e.length > 1}
# => {1=>[1, 1, 1], 2=>[2, 2]}
If you want just the values:
dups.keys
# => [1, 2]
If you want the number of duplicates:
dups.map{|k, v| {k => v.length}}
# => [{1=>3}, {2=>2}]
Might want to monkeypatch Array if using this more than once:
class Array
def uniq?
self.length == self.uniq.length
end
end
Then:
irb(main):018:0> [1,2].uniq?
=> true
irb(main):019:0> [2,2].uniq?
=> false

Resources