Ruby version: Confirmed operation with 2.5.1.
Until now, I've only used the ʻeach method` when it comes to array methods. (I'm a beginner about 2 months after I started learning programming in earnest.) When developing a personal application with Rails, I often say "I want to process the array data obtained from the DB table well and display only the necessary elements, but I can't do it well". While researching various things to solve the problem, I learned a lot, "Is there such a convenient method!", So I will write it as a memorandum as well as to establish my knowledge.
I hope it will be helpful to anyone.
Junichi Ito's "Introduction to Ruby for Professionals"
Mr. Ito's Qiita articles, books, etc. are very easy to understand and are always indebted.
users = [
{name: 'Matsuda', score: 80},
{name: 'Otsuka', score: 60},
{name: 'Koike', score: 90},
{name: 'Inoue', score: 40},
{name: 'Matsumoto', score: 50},
{name: 'Fujisawa', score: 85}
]
I will explain each method while checking the operation below.
The select method
performs the processing specified in the block for each element of the array. Returns an array of only the elements whose return value is true
.
select.rb
#I want only users with a score of 70 or higher!
users = [
{name: 'Matsuda', score: 80},
{name: 'Otsuka', score: 60},
{name: 'Koike', score: 90},
{name: 'Inoue', score: 40},
{name: 'Matsumoto', score: 50},
{name: 'Fujisawa', score: 85}
]
#Collect only users with score 70 or higher using select
goukaku_users = users.select { |user| user[:score] >= 70 }
#Check the contents of the newly created variable
p goukaku_users
# =>[{:name=>"Matsuda", :score=>80}, {:name=>"Koike", :score=>90}, {:name=>"Fujisawa", :score=>85}]
#I was able to create an array only for users with a score of 70 or higher!
do ... end
is written in one line of notation using{}
.
It's a shame, but I'm sorry if it's hard to understand the variable name.The reject method
is the opposite of the select method
, and is a method that returns an array that collects only the elements whose return value of processing in the block is false
.
reject.rb
#I want only users with a score of 70 or less!
users = [
{name: 'Matsuda', score: 80},
{name: 'Otsuka', score: 60},
{name: 'Koike', score: 90},
{name: 'Inoue', score: 40},
{name: 'Matsumoto', score: 50},
{name: 'Fujisawa', score: 85}
]
#Collect only users with score 70 or less with reject method
fugoukaku_users = users.reject { |user| user[:score] > 70 }
#Check the contents of the newly created variable
p fugoukaku_users
# => [{:name=>"Otsuka", :score=>60}, {:name=>"Inoue", :score=>40}, {:name=>"Matsumoto", :score=>50}]
#I was able to create an array only for users with a score of 70 or less!
The keep_if method
also retrieves each element of the array in order and performs the specified processing in the block. As a result, if the return value is true
, the element passed to the block is left in the array, and if the return value is false
, it is deleted from the array.
keep_if.rb
#I want only users with a score of 70 or higher!
users = [
{name: 'Matsuda', score: 80},
{name: 'Otsuka', score: 60},
{name: 'Koike', score: 90},
{name: 'Inoue', score: 40},
{name: 'Matsumoto', score: 50},
{name: 'Fujisawa', score: 85}
]
# keep_Process only users with score of 70 or more with if method
#Removed users element with score less than 70
users.keep_if { |user| user[:score] >= 70 }
# keep_After the if method
p users
# => [{:name=>"Matsuda", :score=>80}, {:name=>"Koike", :score=>90}, {:name=>"Fujisawa", :score=>85}]
#The original array users can now be an array of only users with a score of 70 or higher!
The delete_if method
also retrieves each element of the array in order and performs the specified processing in the block. As a result, if the return value is true
, the element passed to the block is deleted from the original array. If the return value is false
, leave it in the array.
delete_if.rb
#I want only users with a score of 70 or less!
users = [
{name: 'Matsuda', score: 80},
{name: 'Otsuka', score: 60},
{name: 'Koike', score: 90},
{name: 'Inoue', score: 40},
{name: 'Matsumoto', score: 50},
{name: 'Fujisawa', score: 85}
]
# delete_Process only users with score of 70 or less with if method
#Removed users element with score greater than 70
users.delete_if { |user| user[:score] > 70 }
# delete_After the if method
p users
# => [{:name=>"Otsuka", :score=>60}, {:name=>"Inoue", :score=>40}, {:name=>"Matsumoto", :score=>50}]
#The original array users has been changed to an array of only users with a score of 70 or less!
The keep_if
and delete_if methods
are the same as the select method
and reject method
explained in 1 and 2 !?
I thought, but when compared
select / reject The original array remains the same, but the elements that meet the conditions are collected and a completely new array is returned. Therefore, when reusing it, assign it to a variable. delete_if / keep_if Delete the elements that meet the conditions from the original array. In other words, the shape of the original array itself is changed. Therefore, it can be reused with the original variable name.
It's similar, but there seems to be such a difference.
The find method
returns the first element for which the return value of the process specified in the block is true
.
find.rb
#I want to get the first user with a score of 70 or more in the array users!
users = [
{name: 'Matsuda', score: 80},
{name: 'Otsuka', score: 60},
{name: 'Koike', score: 90},
{name: 'Inoue', score: 40},
{name: 'Matsumoto', score: 50},
{name: 'Fujisawa', score: 85}
]
#Get the first user with a score of 70 or higher with the find method
goukaku_user = users.find { |user| user[:score] >= 70 }
#Check the contents of the newly created variable
p goukaku_user
# => {:name=>"Matsuda", :score=>80}
#I was able to get the first user with a score of 70 or higher in the array!
Just in case, try changing the condition of the score in the block from 70 to 85 and verify again.
find.rb
#I want to get the first user with a score of 85 or higher in the array users!
users = [
{name: 'Matsuda', score: 80},
{name: 'Otsuka', score: 60},
{name: 'Koike', score: 90},
{name: 'Inoue', score: 40},
{name: 'Matsumoto', score: 50},
{name: 'Fujisawa', score: 85}
]
#Get the first user with a score of 85 or higher with the find method
goukaku_user = users.find { |user| user[:score] >= 85 }
#Check the contents of the newly created variable
p goukaku_user
# => {:name=>"Koike", :score=>90}
#I was able to get the first user with a score of 85 or higher in the array!
The map method
returns the return value as a new array as a result of the processing specified in the block for each element.
map.rb
#I want to add "san" to the name of the array users!
users = [
{name: 'Matsuda', score: 80},
{name: 'Otsuka', score: 60},
{name: 'Koike', score: 90},
{name: 'Inoue', score: 40},
{name: 'Matsumoto', score: 50},
{name: 'Fujisawa', score: 85}
]
san_users = users.map { |user| user[:name] + 'Mr.' }
#Check the contents of the newly created variable
p san_users
# => ["Mr. Matsuda", "Mr. Otsuka", "Mr. Koike", "Inoue", "Mr. Matsumoto", "Mr. Fujisawa"]
that? It was a little different from what I expected.
The map method
seems to behave a little differently from the array methods described so far.
In particular, Instead of evaluating the elements of the original array and transforming the elements to return the values, the return values of the processing results are stored in the array one by one and the newly created array is returned.
If you know the javaScript map method, it may be easier to understand.
map.rb
#So if you want to return in hash format while maintaining the original shape, write as follows
san_users = users.map { |user| {name: user[:name]+'Mr.', score: user[:score]} }
p san_users
# => [{:name=>"Mr. Matsuda", :score=>80}, {:name=>"Mr. Otsuka", :score=>60}, {:name=>"Mr. Koike", :score=>90}, {:name=>"Inoue", :score=>40}, {:name=>"Mr. Matsumoto", :score=>50}, {:name=>"Mr. Fujisawa", :score=>85}]
#I was able to create an array with "san" added to the name!
Thank you for reading the article.
I am keenly aware that developing with Rails and knowing that I do not know the method will greatly affect the range of things I can do and code refactoring. I am feeling the importance of the basics again.
If you find any mistakes in the content, please feel free to point out and give us your opinion!
Recommended Posts