How to recreate the any? method in Ruby - ruby

I am trying to recreate the enumerable module in Ruby. I am up to the any? method and having difficulty returning true or false. Instead each array item is returned 1 by 1.. Here is my code:
def my_any?
return self.to enum unless block_given?
self.each do |i|
return true if i == yield(i)
end
end
nums = [3,5,7,3,6,10,20,16]
puts nums.my_any?{|x|x==6}
Any ideas where I am going wrong?

You have three issues with your code: you should return an enumerator for this method when called without block, you should check just what yield returns, and you should explicitly return false on fail:
def my_any?
return to_enum(:my_any?) unless block_given?
each { |i| return true if yield(i) }
false
end
nums = [3,5,7,3,6,10,20,16]
puts nums.my_any? { |x| x == 6 }
#⇒ true
lazy = nums.my_any?
lazy.each { |x| x == 6 }
#⇒ true
Or, I would better use break:
def my_any?
return to_enum(:my_any?) unless block_given?
each { |i| break true if yield(i) } == true
end

You have two issues:
You're missing a return false if the loop fails to find a match. Currently when it fails to match, it'll give the return value from each, which is what you're seeing.
It's currently always failing, because while your return true if cond construct is right, any?'s conditional is not i == yield(i): you've got too many comparisons. You need just yield(i).
(The to enum bit sounds off too, but that's unrelated to your question.)
Slotting those changes into your code:
def my_any?
# FIXME: return self.to enum unless block_given?
self.each do |i|
return true if yield i
end
false
end

Related

Hardcoding Ruby Enumerable#reduce - I have two methods, but only one works. Why?

I'm a novice, and as an exercise, I have to hardcode a method that takes an array as an argument, and if ALL elements in that array are truthy, return true. If not, false.
def reduce_to_all_true(array)
array.each do |index|
if !index
return false
end
return true
end
end
This returns true if ANY element is true...
Meanwhile, the following:
def reduce_to_all_true(array)
array.length.times { |index|
if !array[index]
return false
end }
return true
end
Behaves as expected. What I can't work out, is WHY? In my admittedly limited understanding, they are equivalent solutions. Can someone help me understand this? Thank you!
In the first method the return true is inside the #each loop so it will check only the first element and return either true or false. In the second one it's after the loop, so it will return true only if the loop finishes completely wihtout finding any element that's false.
def reduce_to_all_true(array)
array.each do |index| # each loop starts here
if !index
return false
end
return true # this will return true if the first element of array is true
end # and ends here
end
def reduce_to_all_true(array)
array.length.times { |index| # times loop starts here
if !array[index]
return false
end } #and ends here
return true #this will return true only if the times loop finishes
end

creating my own Enumerable method my_none? for Ruby

I have created my own Enumerable method my_none?. It gives me lint error:
Convert if nested inside else to elsif.
Also two of the test cases are not working. Can anyone help me to resolve these issues?
module Enumerable
def my_each
i = 0
while i < size
yield self[i]
i += 1
end
end
def my_none?
my_each do |item|
if block_given?
return false if yield item
else
return false if item
end
end
true
end
end
%w{ant bear cat}.my_none? { |word| word.length == 5 } #=> true
%w{ant bear cat}.my_none? { |word| word.length >= 4 } #=> false
[].my_none? #=> true
[nil].my_none? #=> true
[nil, false].my_none? #=> true
[nil, false, true].my_none? #=> false
The below two test cases are not working:
%w{ant bear cat}.my_none?(/d/) #=> true > gives me wrong no of argument given 1 expected 0
[1, 3.14, 42].my_none?(Float) #=> false > gives me wrong number of argument
my_none? method, as you defined it, does not accept any arguments. It can only accept block.
I think you meant:
%w{ant bear cat}.my_none?{|e| e =~ /d/ }
[1, 3.14, 42].my_none?(&:to_f)
&:to_f is a way to create a Proc - see this question for more info.
To get rid of the lint errors you can change my_none? implementation to:
def my_none?
my_each do |item|
return false if block_given? && yield(item) || !block_given? && item
end
true
end

Determinate which method returns true in or operator

I have:
def user_validation
first_user_valid? || second_user_valid?
end
and I don't only want to return true/false but also want to return which method returns the true (maybe both?). I do have:
def user_validation
return true if first_user_valid?
return true if second_user_valid?
end
so far. But this does not seem very intuitive to me.
Thanks
You can return an array of responses:
def user_validation
[first_user_valid?, second_user_valid?]
end
This way you can know that the first returned true, and the other false...
# => [true, false]
If i were you, i change the return from boolean to int. Doing that, you can handle which statment returning specifics numbers for that.
Why not call the method itself separately for the different users?
def user_validation(user)
return user_valid?
end
if(user_validation(user_1))
//user_1 is valid
end
if(user_validation(user_2))
//user_2 is valid
end
Just out of curiosity:
result = %w|first_user_valid second_user_valid|.inject(nil) |memo, m|
(memo ||= []) << m.tr('_', ' ') if public_send("#{m}?")
memo
end
if result # at least one is valid
puts result.join ', '
else # none is valid
puts 'None is valid :('
end
Result here might be either nil (falsey), or the string like:
"first user valid, second user valid"
def user_validation
valid = ((which = :first) && first_user_valid?) ||
((which = :second) && second_user_valid?)
which = :neither unless valid
[valid, which]
end
To illustrate:
def first_user_valid?; true; end
def second_user_valid?; true; end
user_validation #=> [true, :first]
def first_user_valid?; false; end
user_validation #=> [true, :second]
def second_user_valid?; false; end
user_validation #=> [false, :neither]
In general, when using ||, you don't want to evaluate the second expression if the first evaluates true, as in some cases that may raise an exception (e.g. division by zero), have undesirable side effects (e.g., deleting a needed file) or initiate a lengthy calculation.

Block/Proc with Include for Ruby

I'm trying to think of a way to do this as a proc. Essentially the only part of the code that is different is that on substring match their is a .include? instead of a check for equals.
def check_exact_match(lead_attribute, tracker_attribute)
return true if tracker_attribute.nil?
return true if lead_attribute.downcase == tracker_attribute.downcase
false
end
def check_substring_match(lead_attribute, tracker_attribute)
return true if tracker_attribute.nil?
return true if lead_attribute.downcase.include? tracker_attribute.downcase
return false
end
I'm not sure if I remember how to code in Ruby elegantly, but what about something like this?
def check­_match(lea­d_attribut­e, track­er_attribu­te)­
track­er_attribu­te.nil? or yield lead_­attribute,­ track­er_attribu­te
end
The function can then be called like this:
check_match("abcd", "bd") { |l, t| l.downcase == t.downcase }
check_match(la, ta) { |l, t| l.downcase.include? t.downcase }
Modification from #busy_wait.
def check­_match(lea­d_attribur­e, track­er_attribu­te, &condition)­
track­er_attribu­te.nil? or condition.­call(lead_­attribute,­ track­er_attribu­te)
end
def check_exact_match(lead_attribute, tracker_attribute)
check_match(lea­d_attribur­e, track­er_attribu­te) { |l, t| l.downcase == t.downcase }
end
def check_substring_match(lead_attribute, tracker_attribute)
check_match(lea­d_attribur­e, track­er_attribu­te) { |l, t| l.downcase.include? t.downcase }
end

How do I use regular expressions in Ruby?

I don't know how to implement regular expressions in Ruby. I tried this code, but it always returns true:
firstName = "Stepen123"
res = Validation_firstName(firstName)
puts res
def Validation_firstName(firstName)
reg = /[a-zA-z][^0-9]/
if reg.match(firstName)
return true
else
return false
end
end
I am not sure what I did wrong.
You can rewrite your method like this:
def validation_firstname(first_name)
!!first_name[/^[a-z]+$/i]
end
def validation_firstname(first_name)
first_name.scan(/\d+/).empty?
end
p validation_firstname("Stepen123") #=> false
p validation_firstname("Stepen") #=> true

Resources