Search

検索したいワードを入力してください

2019年04月10日

Rubyのinjectメソッドを使った繰り返しを行う方法

この記事では、Rubyのinjectメソッドについて解説しています。特殊な処理をするプログラムなので少し理解が難しいかもしれません。しかし、とても便利なメソッドなのでぜひ理解できるようにこの記事を活かしていただきたいと思います。

Rubyのinjectメソッドとは

Rubyのinjectメソッドは、配列の各要素対しての処理を提供するメソッドです。Rubyの配列の各要素に対するメソッドといえば、mapメソッドやeachメソッドが代表的ですが、このinjectメソッドも同じように処理を行います。injectメソッドは、配列の各要素に対して、処理の結果を利用しながらループさせたい場合に利用するメソッドです。

すこし特殊な動作をするメソッドなので理解が難しいかもしれません。しかし、このメソッドを使えるようになると他のRubyメソッドで行っていた処理をスリムに記述することができます。それにより、可読性が上がりメンテナンス性の高いプログラムとすることにも繋がります。

ぜひこのinjectメソッドを理解して、よりよいRubyプログラムを書けるようになりましょう。

injectメソッドの基本的な使い方

injectメソッドの基本的な使い方について解説します。
プログラム上では配列.inject{|記憶変数, 要素変数| 処理}というように記述します。
記憶変数と要素変数にはそれぞれ、「配列要素1, 配列要素2」、「前の処理の返り値, 配列要素3」、「前の処理の戻り値、配列要素4」・・・というように渡されていきます。この渡された「前の処理の戻り値」を用いて、要素ごとに処理をおこなっていきます。

以下にサンプルコードを示します。

array = ['taro', 'jiro', 'sabro', 'shiro']
puts array.inject{|memo, item| memo. + ', ' + item} #taro, jiro, sabro, shiro


上記のコードは、配列要素を文字列に変換しています。処理のフローとしては、まずmemoに配列要素1の「'taro'」が渡され、itemに配列要素2の「'jiro'」が渡され、処理が行われます。

次に、memoには処理の戻り値「'taro, jiro'」が渡され、itemには配列要素3の「'saburo'」が渡されます。こういった形で最後の配列要素までアクセスされ、結果「taro, jiro, sabro, shiro」という結果が得られます。

初期値をinjectの引数の0で初期化してsumを算出する

なお、injectメソッドには初期値を渡すことができます。その場合は、配列.inject(初期値){|記憶変数, 要素変数| 処理}という書き方になります。こちらは初期値を設定する書き方です。この場合だと、最初の記憶変数に初期値が渡されます。

つまり、記憶変数と要素変数にはそれぞれ、「初期値, 配列要素1」、「前の処理の返り値, 配列要素2」・・・というように渡されていきます。

これを用いて、数字要素配列のsumを算出するコードを書いてみます。

array = 1..100
puts array.inject(0){|sum, item| sum+item} #5050


このコードの処理のフローとしては、まずsumに初期値の0が渡され、itemに配列要素1の「1」が渡され、処理が行われます。そしてsumには処理の結果(ここでは1)が渡され、item配列要素2の「2」が渡されます。そして再度処理が行われます。これが配列要素100まで繰り返し行われることで、結果が返されます。

このように、injectメソッドは初期値を利用して処理を行うこともできます。初期値を利用するかどうかは状況によりますが、初期値をうまく利用して正確なプログラムを記述できるようにしましょう。

injectにシンボルを使って演算子を指定する

injectメソッドには、便利な機能があります。injectメソッドの引数に演算子を指定することで、配列要素全てに対してその演算子の処理を行わせることができるという機能です。この演算子はシンボル(頭に:を付ける書き方)で指定する必要があります。

プログラム上では配列.inject(演算子シンボル)と指定します。処理の部分の記述は不要です。なお、初期値を設定した上で演算子を指定する場合は、配列.inject(初期値, 演算子シンボル)と指定すればOKです。

以下の項で、injectと他のメソッドをそれぞれ使って、1〜100までの数値をもった配列に対してその要素全てを足す処理を考えていきます。injectメソッドの便利な点を理解していきましょう。

eachで書く方法

まずは、eachで記述する方法を紹介します。サンプルコードを示します。

array = 1..100
sum = 0
array.each{|item| sum += item}
puts sum #5050

上記のコードは、上から「配列定義」、「sumの初期化」、「ループ処理にて加算処理」、「結果の表示」が行われています。つまり、array配列の各要素を加算するだけで4行の処理を書く必要があります。

今回は単純な処理なので4行で済みますが、これが少し複雑な処理となってしまうと更に多くの行数がかかることになります。

injectで書く方法

次に、injectメソッドを用いて1〜100までの要素を加算する処理を紹介します。前章でも同様の処理を行っていますが、今回は演算子シンボルを利用してさらにシンプルな記述になるようにします。

以下にサンプルコードを示します。

array = 1..100
array.inject(0, :+); #5050


上記のコードでは、上から「配列定義」、「配列に対し、初期値0で全ての要素を+演算子にて計算する」という処理が行われています。たった2行で配列要素の加算を表現することができました。

このように、injectメソッドをうまく利用すると、配列に対する処理の記述量を減らし、よりシンプルなコードで表現することが可能になります。

hashに対してinjectを利用する

injectメソッドは、hashに対しても処理をさせることが可能です。hash.inject{|記憶変数, (キー変数, バリュー変数)| 処理}またはhash.inject(初期値){|記憶変数, (キー変数, バリュー変数)| 処理}と記述します。配列のときの使い方と異なるのは、{}内の第二引数にキー変数とバリュー変数の2つが渡されることです。

hashに対してのinjectメソッドの場合の処理のフローは、まず「hashの一番上の要素」が記憶変数に渡され、「hashの二番目の要素」がそれぞれキーとバリューに分かれて変数に渡されます。そして次には記憶変数には「前の処理の結果」が渡され、「hashの3番目の要素」がそれぞれキーとバリューの変数に渡されます。

また初期値がある場合は、記憶変数に最初に渡されるのが初期値となり、hashの一番上の要素がキーとバリューに分かれて変数に渡されるようになります。

以下にサンプルコードを示します。
scores = { math: 67, japanese: 89, english: 54};
puts scores.inject(0){|sum, (key, value)| sum + value}; #210


上記のサンプルは、hashのバリューの値をinjectを使って全て合計した値を返しています。このようにinjcetは、hashに対しても利用することが可能です。

もちろん、キーの方を扱うこともできます。
scores = { math: 67, japanese: 89, english: 54};
puts scores.inject([]){|subjects, (key, value)| subjects << key if value > 60; subjects }; #[math, japanese]


上記のサンプルでは、バリューが60より大きい要素のキーを配列要素としてまとめた配列を返しています。injectメソッドの処理の中に条件分岐を含める場合は上記のように書けるので覚えておきましょう。

上記のコードをeachを用いて書くと以下のようになります。
scores = { math: 67, japanese: 89, english: 54};
subjects =[]
scores.each do | (key, value ) |
if value > 60
subjects << key
end
end
puts subjects #[math, japanese]


処理が少し冗長になっているのがわかります。

なお、injectメソッドなど、配列をループして扱うRubyのメソッドを利用する際の処理ではより省略した演算子を利用するとスリムにプログラムを記述できます。以下に参考サイトを載せておくので参考にしてみましょう。

injectメソッドのまとめ

この記事では、Rubyのinjectメソッドの使い方について解説しました。少し特殊な動作をするメソッドなので理解するのが難しいかもしれませんが、使い方がわかるととても便利なメソッドなのでぜひ理解するようにしましょう。

またhashでのinjectの使い方についても解説しました。Rubyにおいてはhashでデータを保持することも多いので、hashに対してさまざまな処理をスムーズに行えるようになっておくのは必須スキルといえます

ぜひhashに対するinjectの使い方を理解して、よしなに処理を行えるようになっておきましょう。

多くの人がプログラミングを諦めてしまう理由をご存知ですか?



近年プログラミングを勉強する人が増えています。

プログラミング学習者の多くは独学から取り組もうとしますが、だいたい80%ほどは3ヶ月も続かずに諦めてしまいます。早い人は1日目で。

多くの人がプログラミングを独学しようとして諦める理由は、次の3つ。
●モチベーションが維持できない
●エラーの原因・解決方法が分からない
●どう学習すればよいか分からない

TechBoostというプログラミングスクールでは、みんなと一緒にプログラミングをするのでモチベーションの維持ができ、分からないことがあればマンツーマンで教えてくれ、徹底的に研究された初心者向けの教材が揃っています。

TechBoostを卒業後、実際にエンジニアとして転職した方もいるほど。

本気でプログラミングを学びたい方は、一度無料のカウンセリングでご相談ください。プログラミングを嫌いになる前に。

tech boost卒業生インタビュー

tech boostの卒業生の声を聞きました。あなたがプログラミングを学びたい理由を、一度考えてみてください。
営業→Javaエンジニア→Rubyエンジニアと転向し、第一志望のFinTech企業で働く山下さん
元営業、ビジネスのわかるエンジニアを目指す菅原さん
サンフランシスコに交換留学し、シリコンバレーのVCでインターン中の梅本さん
予備校の営業から半年でエンジニア転職を果たした小田島さん

tech boostの口コミ



Related