This question already has answers here:
Iterate Array and add each consecutive array value
(2 answers)
Closed 7 years ago.
I'm trying to figure out a way to use Ruby's combination method to return combinations whos sum equals a certain amount. I may not be familiar enough with Ruby or understand if I can add any lambda expressions essentially to the combinations result, is there a way to do what I want with the combination method or is it very limited? Like can you add extra criteria around the combinations result based on some criteria?
combination returns an Enumerator, which you can then filter to get only the combinations you want.
Take this example:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10].combination(2).
select { |n| n.reduce(:+) == 8 } # => [[1, 7], [2, 6], [3, 5]]
Related
This question already has answers here:
What does map(&:name) mean in Ruby?
(17 answers)
Closed 2 years ago.
I done a coding challenge in Ruby not too long ago and wanted a better understanding of how the syntax below works, particularly with the last part of the expression (&:first).
def remove_every_other(arr)
arr.each_slice(2).map(&:first)
end
For some background the task was to take an array and remove every second element from the array.
Tests:
Test.assert_equals(remove_every_other(['Hello', 'Goodbye', 'Hello Again']), #=> ['Hello', 'Hello Again'])
Test.assert_equals(remove_every_other([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]), #=> [1, 3, 5, 7, 9])
Test.assert_equals(remove_every_other([[1, 2]]), #=> [[1, 2]])
Test.assert_equals(remove_every_other([['Goodbye'], {'Great': 'Job'}]), #=> [['Goodbye']])
Test.assert_equals(remove_every_other([]), [])
& is a reference to a method.
:first is a symbol.
So &:first is simply a reference to the method named first in any object.
So this is the same thing as saying arr.each_slice(2).map {|it| it.first }.
When you map a method to elements of a collection, Ruby will simply call that method on the elements of the collection. In your case, arr.each_slice(2) will return elements of arr two by two (see the doc for each_slice), so if your array is e.g. [1, 2, 3, 4, 5, 6, 7, 8] it is a collection containing [[1, 2], [3, 4], [5, 6], [7, 8]]. Mapping :first on that collection means calling the first method on each element, and [1, 2].first simply returns 1 while [7, 8].first returns 7.
As the map method returns a collection with each element replaced with the result of the call to the method, you'll find yourself with a collection containing the first of each pair. This is how it removes every other element.
Note that if the original collection has an odd number of elements then the last one will be an array of one instead of two (see doc for each_slice), so if the array is [1, 2, 3] the slices are [[1, 2], [3]] and calling .first on each will result in [1, 3].
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).
I want to extract certain values from one array and concat them into another empty one:
freqs=[1,12,4,15,7,8,11,5,6]
less_freqs=[]
This is what I've come up with.
freqs.collect{|x| x<9 then x.to_a{|y|less_freqs<<y}}
Perhaps a different method? And, I'm not even sure if then makes any sense.
Is this what you're looking for?
freqs = [1,12,4,15,7,8,11,5,6]
less_freqs = freqs.select{|x| x < 9 } # => [1, 4, 7, 8, 5, 6]
I have created several arrays, containing multiple integers. Now i want the integers to be sorted, lowest first. Say for instance, i have this in an array: 6,6,1,2,4,4, i want it to be sorted: 1,2,4,4,6,6. Also, is there anyway i can make ruby recognize the 4 lowest values, and display them somehow? I have tried to mess around with .show, but since im quite new to programming i'm rather confused by the results i receive.
did you try this?
a = [6,6,1,2,4,4]
p a.sort
#=> [1, 2, 4, 4, 6, 6]
sort will sort in ascending order.
if you need them sorted in descending order, use sort with a block:
p a.sort {|a,b| b <=> a}
#=> [6, 6, 4, 4, 2, 1]
UPDATE: not sure how i missed the part about lowest values ...
thank you #Mladen
a.sort.take(4)
#=> [1, 2, 4, 4]