Odd (or even) entries in a Ruby Array
a = ('a'..'z').to_a
a.values_at(* a.each_index.select {|i| i.even?})
# => ["a", "c", "e", "g", "i", "k", "m", "o", "q", "s", "u", "w", "y"]
a.values_at(* a.each_index.select {|i| i.odd?})
# => ["b", "d", "f", "h", "j", "l", "n", "p", "r", "t", "v", "x", "z"]
So, as requested
class Array
def odd_values
self.values_at(* self.each_index.select {|i| i.odd?})
end
def even_values
self.values_at(* self.each_index.select {|i| i.even?})
end
end
Selecting the odd or even elements out of an array
If you add this code you have 2 handy methods to select odd or even values from an array
class Array
def odd_values
values_at(* each_index.select(&:odd?))
end
def even_values
values_at(* each_index.select(&:even?))
end
end
Ruby .each_slice with condition even and odd indexes of an array
newArrayOne, newArrayTwo = array.partition.with_index { |_,i| i.even? }
Sort odd numbers in array while keeping even numbers in place
Here are a couple of ways to do that.
arr = [7, 5, 35, 8, 12, 17, 47, 47, 37, 64, 22, 55, 13]
Both begin with the following calculation
odd, even = arr.each_with_index.partition { |n,i| n.odd? }
#=> [[[7, 0], [5, 1], [35, 2], [17, 5], [47, 6], [47, 7], [37, 8], [55, 11], [13, 12]],
# [[8, 3], [12, 4], [64, 9], [22, 10]]]
odd
#=> [[7, 0], [5, 1], [35, 2], [17, 5], [47, 6], [47, 7], [37, 8], [55, 11], [13, 12]]
even
#=> [[8, 3], [12, 4], [64, 9], [22, 10]]
See Enumerable#each_with_index, Enumerable#partition and Integer#odd?.
#1
odd_val, odd_idx = odd.transpose
#=> [[7, 5, 35, 17, 47, 47, 37, 55, 13],
# [0, 1, 2, 5, 6, 7, 8, 11, 12]]
a = even.concat(odd_val.sort.zip(odd_idx))
#=> [[8, 3], [12, 4], [64, 9], [22, 10], [5, 0], [7, 1], [13, 2],
# [17, 5], [35, 6], [37, 7], [47, 8], [47, 11], [55, 12]]
h = a.map(&:reverse).to_h
#=> {3=>8, 4=>12, 9=>64, 10=>22, 0=>5, 1=>7, 2=>13, 5=>17, 6=>35, 7=>37,
# 8=>47, 11=>47, 12=>55}
h.values_at(*0..arr.size-1)
#=> [5, 7, 13, 8, 12, 17, 35, 37, 47, 64, 22, 47, 55]
Note:
odd_val.sort.zip(odd_idx)
#=> [5, 7, 13, 17, 35, 37, 47, 47, 55].zip([0, 1, 2, 5, 6, 7, 8, 11, 12])
#=> [[5, 0], [7, 1], [13, 2], [17, 5], [35, 6], [37, 7], [47, 8], [47, 11], [55, 12]]
See Array#sort, Array#zip and Hash#values_at.
#2
a = odd.map(&:first).sort
#=> [5, 7, 13, 17, 35, 37, 47, 47, 55]
even.each { |n,i| a.insert(i,n) }
a #=> [5, 7, 13, 8, 12, 17, 35, 37, 47, 64, 22, 47, 55]
See Array#insert.
Need help filtering an array?
You want to delete odd numbers but your program is deleting even numbers (x % 2 == 0
checks if x is an even number)
METHOD 1:
arr = [1, 2, 3, 4, 5, 6, 7, 8, 10]
arr.delete_if &:odd?
print arr
delete_if iterates by incrementing the index for arr, and deletes an element immediately after evaluating the block &:odd?
with respect to the element. In other words, it is going through each element in array, and deleting the element if &:odd?
is true.
&:odd?
: a lambda function passing in an object to the odd?
method, which returns true if the object is an odd number. Further explanations can be found what is the functionality of "&: " operator in ruby?
Note that method 1 actually MODIFIES the original array. For a way to create a new array of non-odd numbers, there is...
METHOD 2:
non_odds = arr.select{|i| not i.odd?}
Ruby sorting even and odd numbers issue
First off, let's fix your indentation (and convert to standard Ruby community coding style), so that we can better see what's going on:
[1, 2, 3, 4, 5, 6].sort do |x, y|
if x.odd? && y.odd?
0
elsif x.odd?
-1
else
1
end
if (x.odd? && y.odd?) || (x.even? && y.even?)
x <=> y
end
end
Now, the problem becomes obvious: your first conditional expression evaluates to 0
, -1
, or 1
, but nothing is being done with this value. The value is not stored in a variable, not passed as an argument, not returned. It is simply ignored. The entire expression is a NO-OP.
Which means that the only thing that matters is this:
if (x.odd? && y.odd?) || (x.even? && y.even?)
x <=> y
end
This will return 0
for two elements that are equal, -1
or 1
for two elements that are unequal but both odd or both even, and nil
(which to sort
means "these two elements are un-comparable, they don't have a defined relative ordering") for elements where one element is odd and one is even. Since sort
requires all elements to be comparable, it will then abort.
The easiest way to approach this problem would probably be to partition the array into odds and evens, sort them separately, and then concatenate them:
[1, 2, 3, 4, 5, 6].partition(&:odd?).map(&:sort).inject(:concat)
#=> [1, 3, 5, 2, 4, 6]
Or do it the other way round, just sort them all, and then partition (Thanks @Eric Duminil):
[1, 2, 3, 4, 5, 6].sort.partition(&:odd?).inject(:concat)
#=> [1, 3, 5, 2, 4, 6]
Ruby elegant way of adding all even or odd indexed digits of a number?
number.to_s.chars.map(&:to_i). # turn string into individual numbers
partition.with_index { |_, i| i.odd? }. # separate the numbers into 2 arrays
map { |a| a.reduce(:+) } # sum each array
#=> [18, 28]
ruby method returns wrong elements with odd/even index ruby 2.6.0
The problem with your actual code is that index
returns the index of the first element it finds in the receiver. As 1 is 4 times in number
it'll return the index of the first 1 in number
from left to right, same for all other repeated numbers.
An easy solution; use each_with_index
which allows you to iterate over each element in the receiver plus yielding the current index of that element, so you can check if the index is even or not, deciding where to push the element:
array_of_chars.each_with_index do |x, index|
if index.even?
array_even_index << x
else
array_odd_index << x
end
end
Or you can use partition
plus with_index
for that:
array_even_index, array_odd_index = 5169294814153321.digits.reverse.partition.with_index { |_, index| index.even? }
p array_even_index # [5, 6, 2, 4, 1, 1, 3, 2]
p array_odd_index # [1, 9, 9, 8, 4, 5, 3, 1]
Related Topics
How to Use a Rack Middleware Only for Certain Paths
Is a System-Wide Install of Rvm a Bad Idea
Which Gem Support Import/Export to Xlsx File in Ruby
How to Get All Class Names in a Namespace in Ruby
Converting Upper-Case String into Title-Case Using Ruby
Is There an Add_Days in Ruby Datetime
Unknown Ruby Interpreter Version (Do Not Know How to Handle): Ruby_Version
Mailer Unable to Access Reset_Token in User Model
M Hartl's Ruby on Rails Tutorial Chapter 5 Custom Title on Home Page
How to Use Ruby's Readlines.Grep for Utf-16 Files
Why 6.84 - 3.6 == 3.2399999999999998
Tzinfo-Data Present But Not Seen
Inverse of 'Module#Singleton_Class'
Getting Rails Url Helpers to Automatically Output Https Urls