There are two completely identical methods, only one uses each and the other any, so what is the difference between each and any?
first program code (each using):
def is_prime?(num)
Math.sqrt(num).floor.downto(2).each {|i| return false if num % i == 0}
true
end
number = gets.chomp.to_i;
puts is_prime?(number);
second program code (any using):
def is_prime?(num)
Math.sqrt(num).floor.downto(2).any? {|i| return false if num % i == 0}
true
end
number = gets.chomp.to_i;
puts is_prime?(number);
CodePudding user response:
each
is the iterator that go through the array from beginning to end
Its main purpose is just to pass through the array (or other collection) and perform some actions that were specified in the block. For example, it can be a rendering of HTML partial or making HTTP requests or something else
There are also many other iterators that have specific tasks. These are such as map
, select
, any?
and others
You used it wrong way. You're not using the full power of a specific iterator
But you can do it like this:
def prime?(num)
!Math.sqrt(num).floor.downto(2).any? { |i| num % i == 0 }
end
or like this
def prime?(num)
Math.sqrt(num).floor.downto(2).any? { |i| num % i != 0 }
end
CodePudding user response:
The .each
method iterates through all elements of a data structure, most commonly an array or a hash, and calls the given block once for each element. If no block is given, it returns an enumerator, i.e. an instance of the Enumerator class that can then be used to "manually" iterate through the data structure.
The .any?
method tests every element of a data structure against the given condition and returns true
if one or more of them match or pass the test. Otherwise, it returns false
. There are more details to it, so please check it from the official documentation.
General tips using Ruby
Based on this code, there are a couple of suggestions. First, you should not use return
in a block as it makes the method return that value, too, and might not execute the block for more iterations.
Second, you don't need trailing semicolons at the ends of lines.
Short analysis of your code
Both your functions seem to work, at least for some numbers, but it seems that you might not exactly know why. Let's take a closer look at it.
Let's assume num = 5
, for example.
First function, the block variable i
gets assigned to a value of 2, meaning the block does not use the return false
because the test num % i == 0
fails. Instead, the function returns true
from the next line.
Second function, the block variable i
also gets assigned to a value of 2, but again, as the test num % i == 0
fails the result of .any?
is false
, and the function returns true
from the next line.
Now, let's assume num = 4
.
First function, the block variable i
gets again assigned to a value of 2, and since this time the test num % i == 0
passes, the return false
inside the block is executed making the function return false
.
Second function, the block variable i
also gets again assigned to a value of 2, and since the test num % i == 0
passes here as well, the return false
inside the block is executed making the function return false
.
Without the return false
in your second function, the function would always return true
because you would not check the value returned by .any?
, and the function's next line would be executed returning true
.
Mechnicov offers simpler alternatives how to make your function more understandable.