I am trying to find the smallest element in an array.
I tried to do this with finding_smallest
method as follows:
def finding_smallest arr_arg
# first time returns 3;
# second time returns 3 again, even though arr_arg doesn't have it.
p arr_arg
arr_arg.each do |el|
if el < @min
@min = el
end
end
@min
end
def selection_sort array
counter = 0
sorting = ->(arr){
arr_range = arr[counter..-1]
smallest = finding_smallest(arr_range)
p arr_range # first iteration - whole array; second iteration - [1..end of the array]
p smallest # first iteration: 3, second iteration: 3;
first_element_in_range = arr_range[0] # for switching indexes of smallest and first in array
arr_range[arr_range.index(smallest)], arr_range[0] = arr_range[0], arr_range[arr_range.index(smallest)] #switching places
counter += 1
sorting.call(arr_range) unless counter == array.length || arr.nil?
}
sorting.call(array)
end
@array = [78, 42, 51, 49, 74, 53, 66, 39, 40, 3, 66, 100]
@min = @array[0]
selection_sort(@array)
It returns the smallest element from a previous array. I think the problem is that the each
loop doesn't set the value for the second time (or first). What I am doing wrong?
@min
plays [here] a role of global variable (main
’s instance variable.) Once set, it is never updated, since the minimum would never be touched anymore.
You might want to update it’s value on each subsequent call:
def finding_smallest arr_arg
@min = arr_arg.first
arr_arg.each do |el|
if el < @min
@min = el
end
end
@min
end
In ruby we use Enumerable#reduce
for that:
def finding_smallest arr_arg
@min = arr_arg.reduce do |min, el|
el < min ? el : min
end
end