[Ruby] Get array elements alternately.

Purpose

Get the elements of the array alternately and create two arrays. I think there are many ways to do it, but I did this.

I got another answer.

-Another solution taught by @scivola (when the array is even) -Another solution (simpler method) taught by @jnchito

Method

array = ['I', 'Ro', 'Is', 'To', 'Ho', 'What', 'When', 'Chi', 'Ri', 'Nu', 'Ru', 'To']

array_A = []
array_B = []

array.each_with_index { |kana, index| index.even? ? array_A << kana : array_B << kana }

p array_A
# => ["I", "Is", "Ho", "When", "Ri", "Ru"]
p array_B
# => ["Ro", "To", "What", "Chi", "Nu", "To"]

Method used

Method meaning manual
each_with_index Eachelementanditsassociatedsubscript(index)Repeattheprocessfor Enumerable#each_with_index
even? Returnstrueiftheelementiseven Integer#even?
? : Conditionaloperator(Ternaryoperator)If/elsestatementwritteninoneline Operatorexpression
<< 配列に要素をaddtoする Array#<<

Commentary

First, prepare an empty array.

array_A = []
array_B = []

Elements are inserted alternately from the original array array in this. The method used for that is each_with_index.

each_with_index

This method allows the repeating each method to use the index of each element as a variable.

['I', 'Ro', 'Is'].each_with_index { |kana, index| p "#{kana} - #{index}" }
# => "I- 0"
#    "Ro- 1"
#    "Is- 2"

Each element and index of the array array is

0 1 2 3 4 5 6 7 8 9 10 11
I Ro Is To Ho What When Chi Ri Nu Ru To

Therefore, using this, we will put elements in array_A when the index is even, and in array_B when the index is odd.

I used the conditional operator for conditional branching.

?: (Conditional operator)

It branches according to the condition before ?, And before and after :, the processing is divided between true and false.

num = 1

num == 1 ? "This is 1" : "This is not 1"
# => "This is 1"

this is,

num = 1

if num == 1
  "This is 1"
else
  "This is not 1"
end
# => "This is 1"

Has the same meaning as.

Then I used the even? Method to see if the condition was even.

even?

This method returns true if the receiver (on the left side of.) Is even, and false if it is odd.

2.even?
# => true

1.even?
# => false

#0 is also an even number
0.even?
# => true

By the way, you can do the same with calculations using operators.

num = 2

num % 2 == 0
# => true

When a number is divided by 2, if the remainder is 0, it is an even number.

Check if the index is even or odd with even?, and after conditional branching with ?:, The element is added to the array with <<.

<< (Addition)

<< adds an element to the end of the array.

num_array = [1, 2]

num_array << 3

p num_array
# => [1, 2, 3]


Another solution taught by @scivola

array = ['I', 'Ro', 'Is', 'To', 'Ho', 'What', 'When', 'Chi', 'Ri', 'Nu', 'Ru', 'To']

array_A, array_B = array.each_slice(2).to_a.transpose

p array_A
# => ["I", "Is", "Ho", "When", "Ri", "Ru"]
p array_B
# => ["Ro", "To", "What", "Chi", "Nu", "To"]

Method used

Method meaning manual
each_slice Dividetheelementsbythespecifiednumber Enumerable#each_slice
to_a Makeanarray Enumerable#entries
transpose Thinkofanarrayasamatrixandswaprowsandcolumns Array#transpose

Commentary

This time the method creates an array, so you don't need to create an empty array.

First, array_A, array_B =. It uses ** multiple assignment ** (manual).

num_A, num_B = 1, 2

p num_A
# => 1

p num_B
# => 2

By preparing two left sides and two right sides in this way, it is possible to substitute at the same time. We will create two arrays that can be assigned to these two left sides.

First, we use each_slice (2) to divide the array into two chunks.

each_slice

This method passes multiple elements (arrays and range objects) to blocks (* in * {}) by the number specified in ().

[1, 2, 3, 4, 5, 6].each_slice(2) { |n| p n }
# [1, 2]
# [3, 4]
# [5, 6]

Once you've split the original array in two, you have to turn it into an array. The method used for that is to_a.

to_a

This method converts the passed element to an array.

(1..10).to_a
# => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

The above converts consecutive (..) numbers from 1 to 10 into an array.

each_slice returns an object of class Enumerator if you remove {}.

[1, 2, 3, 4, 5, 6].each_slice(2)
# => #<Enumerator: [1, 2, 3, 4, 5, 6]:each_slice(2)>

The to_a method is also a method of the Enumerator class, so it will be used for the passed object and an array will be created.

aa = [1, 2, 3, 4, 5, 6].each_slice(2)

aa.class      # .If you use the class method, the receiver(.Left side of)Will return the class.
# => Enumerator

aa.to_a
# => [[1, 2], [3, 4], [5, 6]]

Finally, divide the array in the two divided arrays on the right side and the left side, and you're done. In other words, taking the above numbers as an example, [[ 1, 2 ],[ 3, 4 ],[ 5, 6 ]] If it can be divided into red number array and blue number array like, the original array will alternate. You've got it and created two arrays.

The method for that is transpose.

transpose

This method treats an array in an array as a matrix and swaps rows and columns.

[[0, 1], [0, 1], [0, 1]].transpose
# => [[0, 0, 0], [1, 1, 1]]

If you compare the numbers of red and blue ,

Red Blue
1 2
3 4
5 6

But,

Red 1 3 5
Blue 2 4 6

It is an image that becomes.

Now that you have two arrays, you can assign them to each variable with multiple assignments.



Another solution taught by @jnchito

array = ['I', 'Ro', 'Is', 'To', 'Ho', 'What', 'When', 'Chi', 'Ri', 'Nu', 'Ru', 'To']

array_A, array_B = array.partition.with_index { |_, index| index.even? }

p array_A
# => ["I", "Is", "Ho", "When", "Ri", "Ru"]
p array_B
# => ["Ro", "To", "What", "Chi", "Nu", "To"]

Method used

Method meaning manual
partition Conditionallybrancheachelementtocreatetwoarrays. Enumerable#partition
with_index Indexescanbeusedforiterativevariables. Enumerator#with_index
even? Returnstrueiftheelementiseven Integer#even?

Commentary

This time too, the method creates an array, so you don't need to define an array for the variable. In addition, use Multiple Assignment to substitute two arrays at the same time.

And the method to create those two arrays is partition.

partition

This method divides each element of the array into two arrays depending on whether the block (* in * {}) condition is met.

[1, 2, 3, 4, 5].partition { |num| (num % 2) == 0 }
# => [[2, 4], [1, 3, 5]]

Use this method to create an array of even and non-even (odd) cases.

However, the block variables that can be used by the partition method can only be element variables. (In the above case, the num part) This time, it is the value of the subscript (index) attached to the element that wants to judge even / odd numbers.

The method needed for that is with_index.

with_index

This method allows you to use index for iterative processing (such as the map method) where index cannot be used as a variable.

['I', 'Ro', 'Is'].map.with_index { |kana, index| "#{index}-#{kana}" }
# => ["0-I", "1-Ro", "2-Is"]

Using this, even? Judges the case where index is even and the case where it is odd, and creates two arrays.

even? (odd?)

This method returns true if the receiver (on the left side of.) Is even, and false if it is odd, as per [#even].

By the way, there is also a method called odd?, Which is the opposite of even?. It returns true if the receiver is odd and false if it is even.

1.odd?
# => true

2.odd?
# => false

Variable _

This time, the only variable used in the partition.with_index block is index, no elements. Therefore, the variable of the element is set to _.

array.partition.with_index { |_, index| index.even? }

Reference: Idiom that makes variable names and block parameters one underscore character --Qiita



Finally

If there is a better way, I would appreciate it if you could teach me. Thank you for visiting.

Recommended Posts

[Ruby] Get array elements alternately.
[Ruby] Array
Ruby two-dimensional array
Ruby array manipulation
[Ruby] Calculation by extracting elements from an array
Examine the elements in the array using the [Ruby] includes? Method
[Ruby] Searching for elements in an array using binary search
[Ruby] Extracting a two-dimensional array
[For Ruby beginners] Explain how to freely delete array elements!
Multiplication in a Ruby array
[Ruby] Get parent module (moved)
[Ruby] Difference between get and post
Sorting hashes in a Ruby array
[Ruby] Extracting double hash in array
[Ruby] Extracting elements with slice method
Hanachan in Ruby (non-destructive array manipulation)
Explanation about Array object of Ruby
What is a Ruby 2D array?