How do print odd numbers using block { } - ruby

I am trying to print my array with just odd numbers using the block method but i am not too sure how to.
I can print odd numbers using no block but do but do not know how to implement it into the block method { }
#non block method
array = [1,2,3,4,5,6,7,8]
array.each do |i|
if i % 2 == 0
puts "#{i}"
end
end
#output of 2 4 6 8
#block method not sure how
array = [1,2,3,4,5,6,7,8]
array.each {|i| put i if i % 2 == 0 end }
#expected output should be 2 4 6 8
Thank you in advanced !

your block is almost correct you just need to remove the end as it's an inline (or trailing) if method, you also need to use puts and not put
array.each {|i| puts i if i % 2 == 0 }
also, note that ruby has a .even? and .odd? methods you can call on integers
array.each {|i| puts i if i.odd? }

Another option is to select the even? elements and print them afterwards:
array.select(&:even?).each { |i| puts i }
Or alternatively via reject and odd?:
array.reject(&:odd?).each { |i| puts i }
The each call isn't really needed, as you can pass an entire array to puts and it will print each element on a separate line:
puts array.select(&:even?)
# or
puts array.reject(&:odd?)
All of the above will generate the same output:
2
4
6
8

Related

How to compare strings for 3/4 matches

Need to compare numbers in an array to 'winning' number. But I have to see if 3 out of 4 match. eg "1234" is my number and winning=["4356","8312","4820","7623"] . In this case "8312" should alert a win because they have 1 2&3 in common. I have to define the numbers in a unit test, then write a function in a separate file then pass that function back into the unit test. Any help would be greatly appreciated. I already wrote a function and test comparing for an exact match and dont have any idea on what next step to take.
function_file
def match(my_num,arr)
matches = []
arr.each_with_index do |v,i|
if my_num == v
matches << my_num
end
end
matches
end
test_file
require "minitest/autorun"
require_relative "close_but_no_func.rb"
class TestWinningNumbers < Minitest::Test
def test_1_equals_1
assert_equal(10-5, 3+2)
end
def test_winning_num
my_num = "1134"
arr=["6028","2088","3058","3476","8740","1134"]
assert_equal(["1134"], match(my_num, arr))
end
end
So let us divide this problem into two seperate problems.
You want a function that counts the number of matching characters.
Then you want to collect these strings together, if they have enough matching characters.
You could for example write a function that checks how many characters of the both strings match.
def count_matching_chars(str1,str2)
# counts how many characters of str1 appear in str2
matching_chars_count = 0
str1.each_char do |char|
matching_chars_count += 1 if str2.include?(char)
end
matching_chars_count
end
puts count_matching_chars("1234", "1134") => 3
puts count_matching_chars("1111", "1134") => 4
puts count_matching_chars("1234", "1111") => 1
This one here ignores the positioning, it just checks, how many of the characters of str1 match one character of str2.
Now you can easily collect these numbers in an array.
def matches(my_num, arr)
result = []
arr.each do |num|
result << arr if count_matching_chars(my_num,num) >= 3
end
result
end
You can write both functions in a more compact way, by using enumerator functions like count and select:
def count_matching_chars(str1,str2)
str1.each_char.count do |char|
str2.include?(char)
end
end
def matches(my_num, arr)
arr.select do |num|
return true if count_matching_chars(num,my_num) >= 3
end
end
Or you then combine everything into one function
def matches(my_num, arr)
arr.select do |num|
true if my_num.each_char.count { |char| num.include?(char)} >= 3
end
end
Now if you just want to check, if it is a winning number. You just return true as soon as you find a match:
def winning_number?(my_num, arr)
arr.select do |num|
return true if my_num.each_char.count { |char| num.include?(char)} >= 3
end
end

Iterate through first n elements of array - if that many exist

I am looking for a more elegant, 'Ruby-ists' way to do the following. Is there any cleaner way to do this?
i=0
array.each do |x|
break if x.empty?
puts x
i+=1
break if i>4
end
I saw that you were calling #empty? on the elements in your array and quitting when you see the first empty element. If you want to preserve that behavior, you could do:
array.first(4).each do |x|
break if x.empty?
puts x
end
A fancier way would be:
array.take_while { |i| !i.empty? }.first(4).each do |i|
puts i
end
I am not sure how many elements you want to print; please note that my examples will print at most 4 elements, whereas your code was printing up to 5.
I'd suggest Array#first as follows:
array.first(4).each do |x|
puts x
end
If you only want to accept the first so many non-nil entries, then filter them out using Array#compact:
array.compact.first(4).each do |x|
puts x
end
If you are concerned about empty values then you could still chain the filters using Array#reject:
array.reject(&:empty?).first(4).each do |x|
puts x
end
Another way:
def printem(a,n)
puts a[0, [a.index(&:empty?) || n, n].min]
end
printem [[], [2],[3],[4],[5],[6]], 4
# <prints nothing>
printem [[1],[2], [],[4],[5],[6]], 4
# 1
# 2
printem [[1],[2],[3],[4],[5],[6]], 4
# 1
# 2
# 3
# 4
printem [[1],[2],[3],[4],[5],[6]], 7
# 1
# 2
# 3
# 4
# 5
# 6

ruby for loop using range class instead of fixnum?

for i in [0..4] do
puts i + 1
end
undefined method `+' for 0..4:Range (NoMethodError)
Why is it not treating each number in the range as a fixnum within the loop?
[0..4] is actually array with one range element, the same as [(0..4)]. You need to change it to (0..4).
Write instead:
for i in 0..4 do
Otherwise you don't have a range, you have an array containing 1 range.
There are different ways to achive a goal:
0.upto(4) { |i|
puts i
}
0.step(4, 1) { |i|
puts i
}
5.times { |i| # 5 for inclusive
puts i
}
for i in 0..4
puts i
end
Everything will output:
# ⇒ 0
# ⇒ 1
# ⇒ 2
# ⇒ 3
# ⇒ 4
Hope it helps.

Ruby's "each" methods not iterating over all items in an array?

I'm trying out the following code:
a = [1,2,3,4]
a.each do
puts "Removing #{a.last}"
a.pop
end
but instead of getting all four numbers popped I only get the first 3. Indeed, doing something like puts a.length returns 1 and puts-ing it shows the element "1" is still there.
How do I need to use the method correctly?
(I'm using Ruby 2.0).
I suspect this is happening because you're iterating over the elements of the list while modifying the list.
Try the following:
a = [1,2,3,4]
until a.empty? do
puts "Removing #{a.last}"
a.pop
end
Problem
While you are iterating over a you are changing it.
Explanation of Problem
That means once you have removed an element the each method gets thrown off because suddenly the number of elements a contains is one less. And thus indexing is also thrown off.
If I just execute this:
a = [1,2,3,4]
a.each do
|thing|
puts thing
a.delete(thing)
end
I will get the output [1,3].
That is because the following happens:
Before I remove the 1 from the list that is at index 0, the 2 is at index 1.
After the 1 is removed the 2 is at index 0 instead of 1 so not the 2 is the next element that is iterated over but the 3!
By the way you can define a local block variable like I did with thing to access each element that you iterate over.
Solution
In order to get what you want you need to create a copy and work on that.
a = [1,2,3,4]
b = a.clone
a.each do
|thing|
puts thing
b.delete(thing)
end
Now a remains the same while you iterate over it and you change b instead.
So at the end of this loop a = [1,2,3,4] and b =[].
After you said a = b you will have the desired result.
Of Course you can adapt this for popping elements from the back. Just make sure to work on a copy so you do not change the element while you are iteration over it.
Some other answers tell why your code does not work.
An alternative way to do it would be like this (provided that you do not have nil or false in a):
a = [1,2,3,4]
while e = a.pop
puts "Removing #{e}"
end
a = [1,2,3,4]
a.length.times do
puts "Removing #{a.last}"
a.pop
end
Look at the output,which makes clear why it seems to you each not getting run with all the array elements. As you are pop(ing)Array#pop, so the elements from the last is deleted. When each passes 2 to the block,then original array a is got empty,so each stops the iteration.:
a = [1,2,3,4]
a.each do |i|
puts i
puts "Removing #{a.last}"
p a.pop
p "========"
end
Output:
1
Removing 4
4
"========"
2
Removing 3
3
"========"
So you can use the below:
a = [1,2,3,4]
(0...a.size).each do |i|
p a.pop
end
Output:
4
3
2
1
Try this:
a.count.times do a.pop and puts "Removing #{a.last + 1 rescue 1}" end
Should do the same in a do loop

How do I know what iteration I'm in when using the Integer.times method?

Let's say I have
some_value = 23
I use the Integer's times method to loop.
Inside the iteration, is there an easy way, without keeping a counter, to see what iteration the loop is currently in?
Yes, just have your block accept an argument:
some_value.times{ |index| puts index }
#=> 0
#=> 1
#=> 2
#=> ...
or
some_value.times do |index|
puts index
end
#=> 0
#=> 1
#=> 2
#=> ...
3.times do |i|
puts i*100
end
In this way, you can replace 3 with any integer you like, and manipulate the index i in your looped calculations.
My example will print the following, since the index starts from 0:
# output
0
100
200

Resources