Skip to content

Instantly share code, notes, and snippets.

@Taishikun0721
Last active January 27, 2021 13:13
Show Gist options
  • Save Taishikun0721/545aa83133c84f3a15b4f82b2eb953e4 to your computer and use it in GitHub Desktop.
Save Taishikun0721/545aa83133c84f3a15b4f82b2eb953e4 to your computer and use it in GitHub Desktop.
【30days_challenge】Enumerableモジュールのメソッドを紹介する

Day 1 mapメソッド

与えられたブロックを評価して、最終的に配列を返す。

p [*1..10].map { |a| a * 2 }

=> [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]

ついでに簡易版を実装してみた。 ほんとはテストも通るようにして、実装したい。

class MyArray
  attr_reader :collection

  def initialize
    @collection = [*1..10]
  end

  def my_map(&block)
    result = []
    collection.each do |list|
      result << yield(list) 
    end
    result
  end
end

result = MyArray.new.my_map { |a| a * 3 }
p result

=> [3, 6, 9, 12, 15, 18, 21, 24, 27, 30]

Day2 all? メソッド

■説明 全ての要素が真だった場合に true を返す。偽が見つかった段階で処理は中断され false を返す。

■例

p [2, 4, 6].each.all? { |num| num.even? }
↓これでも一緒
p [2, 4, 6].each.all?(&:even?)
=> true

p [2, 5, 6].each.all? { |num| num.even? }
↓これでも一緒
p [2, 5, 6].each.all?(&:even?)
=> false

Day3 each_slice メソッド

(気付いたら0時回ったけどセーフということで笑)

引数に渡した数値で配列を区切ってくれるメソッド

■例

array = (1..10).to_a
array.each_slice(3) { |nums| p nums }

=> [1, 2, 3]
   [4, 5, 6]
   [7, 8, 9]
   [10]
配列に格納したら、2次元配列も簡単に作れる。

Day4 min_by メソッド

各要素をブロック内で順番に評価して, 最小だった要素元の要素を返す。

■例

class Animal
  def initialize(name, weight)
    @name = name
    @weight = weight
  end

  def weight
    @weight
  end
end

rabit = Animal.new('rabit', 30)
horse = Animal.new('horse', 200)
elephant = Animal.new('elephant', 1000)

animals = [rabit, horse, elephant]

p animals.min_by(&:weight)

=> #<Animal:0x00007ffac80a0120 @name="rabit", @weight=30>

このケースだと 一番体重が軽い動物の名前とかも簡単に調べられる。 https://docs.ruby-lang.org/ja/latest/class/Enumerable.html#I_MIN_BY

Day5 group_by メソッド

配列の値をブロックの条件ごとにグルーピングできる

■例

array = (1..10).to_a
array << 1
p array.group_by(&:itself).map {|key, value| [key, value.count]}.to_h

=> {1=>2, 2=>1, 3=>1, 4=>1, 5=>1, 6=>1, 7=>1, 8=>1, 9=>1, 10=>1}

array にはわかりやすいように1を代入している itself は self を返すので自分自身の値でグルーピングしている事になる。結果↓

{1=>[1, 1], 2=>[2], 3=>[3], 4=>[4], 5=>[5], 6=>[6], 7=>[7], 8=>[8], 9=>[9], 10=>[10]}

これに対して map でkeyとvalueの配列の総数に変換して to_h で ハッシュにしてあげると 配列内に数字が何個ずつあるかがわかる。だから後から代入した1だけ、2で返ってきている。

Day6 flat_map, uniqメソッド

flat_map , uniq メソッド 最初はflat_mapだけの予定でしたが、コードの都合上2つ紹介します。

flat_map メソッド

flattenmap を合わせたようなイメージ。selfが2次元以上の配列でもそれぞれのブロック内を評価して連結して(1段階ネストを浅くして)返してくれる。


uniq メソッド

その名の通り, selfから重複する値を取り除きます。

require 'byebug'
class Engineer
  def initialize(name)
    @name = name
    @skills = []
  end

  def name
    @name
  end

  def skills
    @skills
  end

  def add(*skill)
    @skills = skill
  end
end


class Company

  def initialize
    @engineers = []
    @technologies = []
  end

  def hire(*engineer)
    @engineers = engineer
  end

  def engineers
    @engineers.map(&:name)
  end

  def technologies
    @engineers.flat_map(&:skills).uniq
  end
end

a = Engineer.new('A')
a.add('Rails', 'Vue', 'Firebase', 'COBOL', 'WordPress', '筋トレ')
b = Engineer.new('B')
b.add('Rails', 'Qiita', 'English', 'バスケ')
company = Company.new
company.hire(a, b)
p company.technologies
=> ["Rails", "Vue", "Firebase", "COBOL", "WordPress", "筋トレ", "Rails", "Qiita", "English", "バスケ"]
p company.engineers
=> ["A", "B"]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment