9
5

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.

[初心者向け]リスト操作関数map,reduce,filterの各言語の簡単なサンプル

Last updated at Posted at 2019-05-25

各言語のリスト操作でよく使われるmap filter reduceの簡単な操作を並べてみました。
Javaは冗長ですね。Ruby と Haskellはすごく簡潔です。
ただし、私が普段の業務で使うのがJavaなので、他の言語のことをよく知らずですので、
もっと簡潔に書ける方法があるかもしれません。

  • Java 1.8
  • Ruby 2.6
  • Python 3.7
  • Haskell GHC version 8.0.1
  • Clojure 1.9.0

の簡単な例になります。

数値のリストを作る

ちなみに、業務では固定でリストを初期化することはあまりないと思われます。
普通はリスト系のデータはファクトリーメソッドにて生成されて参照すると思います。
ただし、私はテストなどでテストデータとして以下のような初期化をすることはあります。

Java
    List<Integer> xs = Arrays.asList(1, 2, 3, 4, 5);
    //または @saka1029 さんに教えていただいた、Java 10以降なら
    var xs = List.of(1, 2, 3, 4, 5);

    //こんな無限リストを使うやり方もあります。業務ではこれもしない?
    //外からseed値、function,limit値をいれて作れる。
    xs = Stream.iterate(1, i -> i + 1).limit(5).collect(toList())
Ruby
    xs = [1, 2, 3, 4, 5]
    # 実際には上はあまりよくない例であるらしく、
    # @scivolaさんより教えていただいた以下の方が初期化としてはよいです。
    xs = [*1..5]
Python
	xs = [1, 2, 3, 4, 5]
Haskell
    xs = [1, 2, 3, 4, 5]
    -- または
    xs = [1..5]
Clojure
    (def xs '(1 2 3 4 5))
    ;または @lagenorhynque さんにコメントいただいた方法
    (def xs (range 1 (inc 5)))

以下このリストをすでに作っているものとします。

map 関数

リストをとって各値を2倍にする。

各言語とも結果は[2, 4, 6, 8, 10] になります。
print関数は省略します。

Java
	xs.stream().map(i -> i * 2).collect(toList());
Ruby
	xs.map {|i| i * 2}
Python
	list(map(lambda i: i * 2, xs))
	# 多分この答えを出す場合、Pythonではリスト内包表記を使うのが普通と思われる。
	[i * 2 for i in xs]
Haskell
	map (*2) xs
Clojure
    (map (fn [n] (* n 2)) xs)
    ; または@lagenorhynqueさんにおしえていただいたもの。こっちのが簡潔でいいですね!
    (map #(* % 2) xs)

filter関数

偶数だけ選んで返す。

結果は[2, 4]になります。

Java
	xs.stream().filter(n -> n % 2 == 0).collect(toList());
Ruby
	xs.select(&:even?)
Python
	list(filter(lambda n: n % 2 == 0, xs))
	#多分普通上のような書き方はせずリスト内包表記になると思います。
	[n for n in xs if n % 2 == 0]
Haskell
	filter even xs
Clojure
	(filter even? xs)

reduce関数

リストの数字を加算して集約して返す。

結果は15になります。

Java
    xs.stream().reduce(Integer::sum).orElse(0);
Ruby

    xs.reduce(:+) 
    #または l.inject(:+)
    #reduce使わない場合
    xs.sum

Pythonは@shiracamusさんよりimportがないとのことで不親切でしたので記載しました。

Python
    from functools import reduce
    from operator import add

    reduce(lambda a, b: a + b, xs)
    # reduce使わない場合
    sum(xs)
    # または@shiracamusさんより教えていただきました、
    reduce(add, xs)
Haskell
	foldl (+) 0 xs
	-- fold使わない場合
	sum xs
Clojure
    (reduce + xs)
    ;@lagenorhynqueさんより教えていただいた
    (apply + xs)
    ;という書き方でも同じ結果です。内部で行われるのは (+ 1 2 3 4 5)
    ; reduceは(+ (+ (+ (+ 1 2) 3) 4) 5)

以上です。

いままで勉強したことのある言語に対して書きましたが、個人的に書いていて気持ちがいいと思ったのはRuby,Clojureです。
なんとなく感じが似ている気がします。(作者がどちらもlispが好きだから?)
Haskellはすごすぎて気持ち悪!(いい意味で)と思うところがあるのですが、楽しい!と思えるのはRuby,Clojureでしょうか?なぜなのかわかりませんが。またHaskellは考え方が他の言語とまるで違うのでなかなか勉強が進まないです。

9
5
14

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
9
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?