27
20

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

select + mapを色々な手段で実装する

Last updated at Posted at 2014-03-01

select + mapを一つのメソッドでの続き。
さしあたって5個書いてみました。

設定課題

  • 絞込:文字列から数値をてきとうに抽出する
  • 加工:数値に変換。+1して返す。

each

他の言語から移ったばかりにとってはまぁ標準的なスタイルかと思います。

def filter_number_and_succ(xs)
	res = []
	xs.each do |x|
		res << $&.to_i.succ if /\d+/ =~ x
	end
	return res
end

p filter_number_and_succ(%w(test-101 102 hoge 003 a002))

##Pros

  • 初心者でもわかりやすい
  • 色々と処理を詰め込める

Cons

  • eachという単語から"配列を変更して返す"という意味が期待できない(resという変数名があるけど・・・)
  • 副作用があるコードが違和感なく書ける

select + map

Ruby初心者脱出した辺りで書きたくなるコードかと思います。

def filter_number_and_succ(xs)
	xs.select { |x|
		/\d+/ =~ x
	}.map { |x|
		$&.to_i.succ if /\d+/ =~ x
	}
end

Pros

  • 初心者でも勉強してもらえば分かってもらえる
  • 絞込と加工が別フェーズになっていて処理が明確

Cons

  • (この例のように)絞込と加工が同じ動作を兼ねる場合は処理が冗長になる
  • 絞込方法、加工方法を外からブロックなどで渡そうとした際にキモいことになる

flat_map

flat_mapは空配列を除去する、という性質があることを利用した方法です。MayBeモナ・・・?

def filter_number_and_succ(xs)
	xs.flat_map { |x|
		next [] unless /\d+/ =~ x
		$&.to_i.succ
	}
end

Pros

  • 一回のループで複数の結果を返すことが出来る
  • nextで空配列を返せば、「結果はいらないよ」ということをそれなりに表現できる

Cons

  • 本当に配列を返したい時は、[[x, y, z]]とか書かなきゃダメでぱっと見よくわからない。

map + compact

結果がいらない場合はnilを返して、compactで皆殺しにする作戦です。

def filter_number_and_succ(xs)
	xs.map { |x|
		$&.to_i.succ if /\d+/ =~ x
	}.compact
end

Pros

  • nilを返せば(または戻り値を指定しなければ)、「結果はいらないよ」ということをそれなりに表現できる

Cons

  • 本当にnilを返したい時はどうにもならない

inject

関数型言語のサンプルで見るやつです。

def filter_number_and_succ(xs)
	xs.inject([]) { |acc, x|
		if /\d+/ =~ x 
			acc + [$&.to_i.succ]
		else
			acc
		end
	}
end

Pros

  • それなりに直感的

Cons

  • ブロックが「Array#+で配列の連結ができる」ということを知ってなければならず、配列がデータ構造の組み立て方を意識しなればならない。
  • その気になれば、ブロック側が途中の計算結果を破壊できるわけで
27
20
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
27
20

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?