This question already has answers here:
Clarification on the Ruby << Operator
(5 answers)
Closed 8 months ago.
I am confused about what the << operator does.
def reconstruct_path(prev, current)
if prev.include? current
p = reconstruct_path(prev, prev[current])
[p] << current
else
current
end
end
Array#<< is known as the "shovel". It pushes "things" into other "things".
Like this in this example:
thing_array = [1, 2, 3, 4, 5]
thing_array << 6
Result: => [1, 2, 3, 4, 5, 6]
So the array thing_array was created with the numbers 1 to 5. By using the shovel it pushes the new entry 6 into the thing_array. It's just a shortcut to make code cleaner and lighter.
I hope that makes sense.
Related
This question already has answers here:
Are there something like Python generators in Ruby?
(5 answers)
Closed 6 years ago.
In Python, we can write something like this to generate all positive integers:
def integer():
count = 0
while True:
count += 1
yield count
Is there a way to write a similar generator in Ruby?
It's very similar:
def integer
Enumerator.new do |y|
n = 0
loop do
y << n
n += 1
end
end
end
That can be used like this:
integer.take(20).inject(&:+)
# => 190
You want a lazy enumerator. In Ruby 2.3.1 (and at least as far back as Ruby 2.2.0), you can make one yourself by mixing in Enumerator::Lazy.
However, if all you want is an infinite stream of integers, you could just use a Range object. For example:
(1 .. Float::INFINITY).take 10
#=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
This question already has answers here:
What does the (unary) * operator do in this Ruby code?
(3 answers)
What does the * (star) mean in Ruby? [duplicate]
(1 answer)
Closed 7 years ago.
I read this code that is about quicksort with monkey-patching for the Array class.
class Array
def quicksort
return [] if empty?
pivot = delete_at(rand(size))
left, right = partition(&pivot.method(:>))
return *left.quicksort, pivot, *right.quicksort
end
end
I don't know what the star (*) sign seen at the start of *left.quicksort is. Can't we just use left.quicksort?
The star (in this case) stands for array unpacking. The idea behind it is that you want to get one array with the given elements, instead of array of array, element, array:
left = [1, 2, 3]
pivot = 4
right = [5, 6, 7]
[left, pivot, right] # => [[1, 2, 3], 4, [5, 6, 7]]
[*left, pivot, *right] # => [1, 2, 3, 4, 5, 6, 7]
The * takes a list of arguments and splits them into individual elements.
This allows you to return one un-nested array even when the left and right themselves return an array.
Regarding can't we just use left.quicksort did you give it a try?
def a()
return *[1,2,3], 4, *[5,6]
end
def b()
return [1,2,3], 4, *[5,6]
end
b()
=> [[1, 2, 3], 4, 5, 6]
a()
=> [1, 2, 3, 4, 5, 6]
Without the asterisk, you will have three values returned... the first and last value will be a single array with multiple values
[array1], pivot, [array2]
With the asterisk, the array values will be returned as separate components...
array1_value_1, array1_value_2, array1_value_3, ..., pivot, array2_value_1, array2_value2, array2_value_3, ...
This question already has answers here:
How are array.each and array.map different? [duplicate]
(4 answers)
Closed 9 years ago.
Examining the following code
[1,2,3,4].map # => #<Enumerator: [1, 2, 3, 4]:map>
[1,2,3,4].each # => #<Enumerator: [1, 2, 3, 4]:each>
we can see that both are an enumerator. One is map and other is each. The method to_enum also returns an enumerator each. Is there any difference between these two enumerators?
Yes, when you iterate over the map enumerator, it will take the result and populate it into a new array:
[1,2,3,4].map.each { |n| n * 2 } # => [2, 4, 6, 8]
When you iterate over the each enumerator, it will return the original array
[1,2,3,4].each.each { |n| n * 2 } # => [1, 2, 3, 4]
Map exists to take an array of one type and convert it to an array of a different type, each exists to simply iterate over the array (doing something with a side effect for each element, such as printing it out).
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
ruby array element grouping
Example. Given array a:
a = [1, 2, 3]
Its length is 3 so I want to print all 2-length arrays. These are:
[1, 2]
[1, 3]
[2, 3]
I don't know if there is some method in Ruby to get subset arrays. If there is not such a method what is most efficient way to do achieve this.
That's just a simple combination of 2 elements:
>> xs = [1, 2, 3]
>> xs.combination(xs.size - 1).to_a
=> [[1, 2], [1, 3], [2, 3]]
[EDIT] As #Joshua pointed out in a comment, the docs state that the order is not guaranteed (!). So here is a functional implementation that generates the combinations in the order you asked for. For completeness, I'll make it lazy as the original combination method:
require 'enumerable/lazy'
class Array
def combinations_of(n)
if n == 0
[[]].lazy
else
0.upto(self.size - 1).lazy.flat_map do |idx|
self.drop(idx + 1).combinations_of(n - 1).map do |xs|
[self[idx]] + xs
end
end
end
end
end
This question already has answers here:
Ruby array access 2 consecutive(chained) elements at a time
(4 answers)
Closed 3 years ago.
Say I have a an array like:
a = [1, 2, 3, 4, 5, 6]
and I have two variables like this:
b = 3
c = 4
I want to do something like this:
a.each do |i|
if(b = = i) and (c == i.next(I don't think I can do this))
return true
end
end
Any help would be appreciated.
Steve G.
each_cons does what you want:
a = [1, 2, 3, 4, 5, 6]
b=3
c=4
a.each_cons(2){|v1, v2| puts(b == v1 && c == v2)}
# output:
# false
# false
# true
# false
# false
a.each_cons(2).include?([b,c])
Don't use
a.each_slice
To get a series of paired objects.
Use each_cons as suggested by steenslag or glenn mcdonald.
Do you need to do it in a loop, or could you simply track if each variable is a member? of the array in question? Or put them into a hash/set and make sure each key is contained? Or keep the loop, and just keep logical-ORing whether or each var is a member? Or add a members? method to Array, and pass in an array to check against, or...
That should be enough ideas to get you started.