言語・ライブラリごとのリストやマップ用の便利メソッド使い方比較メモ

`each()` とか `map()` とか、リストやマップを操作する便利メソッドについて、言語ごとにどう書くかのメモ。

対象は、自分がよく使う Java(8 以上), Groovy, JavaScript(Underscore.js, jQuery) だけ。

#リストの各要素を順次処理する
##Java
```java:
import java.util.Arrays;
...

Arrays.asList(1, 2, 3, 4).forEach(System.out::println);
```

##Groovy
```groovy:
[1, 2, 3, 4].each {println it}
```

##JavaScript
コールバックの引数の順序が異なるので注意。

###Underscore.js
```js:
_.each([1, 2, 3, 4], function(e, i, array) {
    console.log(e);
});
```

###jQuery
```js:
$.each([1, 2, 3, 4], function(i, e) {
    console.log(e);
});
```

#リストの中から条件に一致する要素だけを抽出したリストを取得する
##Java
```java:
import java.util.Arrays;
...

Arrays.asList(1, 2, 3, 4).stream()
                         .filter(i -> i % 2 == 0)
                         .forEach(System.out::println);
```

##Groovy
```groovy:
[1, 2, 3, 4].findAll {it % 2 == 0}
            .each {println it}
```

##JavaScript
###Underscore.js
```js:
var array = _.filter([1, 2, 3, 4], function(e) {
    return e % 2 === 0;
});

console.log(array);
```

###jQuery
```js:
var array = $.grep([1, 2, 3, 4], function(e, i) {
    return e % 2 === 0;
});

console.log(array);
```

`each` とは引数の順番が逆になっているので注意。

#リストの中から条件に一致する先頭の要素を取得する
##Java
```java:
import java.util.Arrays;
import java.util.Optional;
...

Optional<Integer> result = Arrays.asList(1, 2, 3, 4).stream()
                                                    .filter(i -> i % 2 == 0)
                                                    .findFirst();

System.out.println(result.get());
```

##Groovy
```groovy:
println([1, 2, 3, 4].find {it % 2 == 0})
```

##JavaScript
###Underscore.js
```js:
console.log(_.find([1, 2, 3, 4], function(e) {
    return e % 2 === 0;
}));
```

###jQuery
なし

#リストの全要素が指定した条件を満たすか確認する
##Java
```java:
import java.util.Arrays;
...

boolean result = Arrays.asList(1, 2, 3, 4).stream().allMatch(i -> i < 10);

System.out.println(result);
```

##Groovy
```groovy:
println([1, 2, 3, 4].every {it < 10})
```

##JavaScript
###Underscore.js
```js:
console.log(_.every([1, 2, 3, 4], function(e) {
    return e < 10;
}));
```

###jQuery
なし

#リストの要素のうち、いずれかが指定した条件を満たすことを確認する
##Java
```java:
boolean result = Arrays.asList(1, 2, 3, 4).stream().anyMatch(i -> i == 3);

System.out.println(result);
```

##Groovy
```groovy:
println([1, 2, 3, 4].any {it == 3})
```

##JavaScript
###Underscore.js
```js:
console.log(_.any([1, 2, 3, 4], function(e) {
    return e === 3;
}));
```

###jQuery
なし

#リストの各要素を処理して別の値に変換し、変換後の値で構築された新しいリストを取得する
##Java
```java:
import static java.util.stream.Collectors.*;
import java.util.Arrays;
import java.util.List;
...

Arrays.asList(1, 2, 3, 4)
      .stream()
      .map(i -> i * 10)
      .forEach(System.out::println);
```

##Groovy
```groovy:
[1, 2, 3, 4].collect {it * 10}
            .each {println it}
```

##JavaScript
###Underscore.js
```js:
var array = _.map([1, 2, 3, 4], function(e) {
    return e * 10;
});

console.log(array);
```

###jQuery
```js:
var array = $.map([1, 2, 3, 4], function(e, i) {
    return e * 10;
});

console.log(array);
```

#リストの各要素から数値を取得し、その合計を取得する
##Java
```java:
import java.util.Arrays;
...

int sum = Arrays.asList("1", "12", "123", "1234")
                .stream()
                .mapToInt(s -> s.length())
                .sum();

System.out.println(sum);
```

`collect(Collectors.summingInt())` や `reduce()` を使う方法もある。

##Groovy
```groovy:
println(["1", "12", "123", "1234"].inject(0, {memo, s -> memo + s.length()}))

println(["1", "12", "123", "1234"].collect {it.length()}.sum())
```

##JavaScript
###Underscore.js
```js:
var sum = _.reduce(['1', '12', '123', '1234'], function(memo, s) {
    return memo + s.length;
}, 0);

console.log(sum);
```

###jQuery
なし

#入れ子になったリストの要素を全て抽出して、１つのリストに入れ替える
Groovy と Underscore.js は、深くネストされたリストでも、再帰的に要素を抽出して平らにしてくれる。
Java の実装例では、１階層までしか見に行かないので、完全に平らにはならない。

##Java
```java:
import java.util.Arrays;
import java.util.List;
...

List<Integer> list1 = Arrays.asList(1, 2);
List<Integer> list2 = Arrays.asList(3, 4);
List<Integer> list3 = Arrays.asList(5, 6);

Arrays.asList(list1, list2, list3)
      .stream()
      .flatMap(list -> list.stream())
      .forEach(System.out::println);
```

##Groovy:
```groovy:
def array = [
    [1, 2],
    [3, 4],
    [5, 6]
]

println array.flatten()
```

##JavaScript
###Underscore.js
```js:
var array = [
    [1, 2],
    [3, 4],
    [5, 6]
];

console.log(_.flatten(array));
```

###jQuery
なし

#要素の重複を取り除く
##Java
```java:
import java.util.Arrays;
...

Arrays.asList(3, 1, 2, 1, 4, 2, 3, 4)
      .stream()
      .distinct()
      .forEach(System.out::println);
```

比較には `equals()` メソッドが用いられる。

##Groovy
```groovy:
println ([3, 1, 2, 1, 4, 2, 3, 4].unique())
```

クロージャーを渡すことで、任意の比較ロジックを指定できる。

##JavaScript
###Underscore.js
```js:
console.log( _.uniq([3, 1, 2, 1, 4, 2, 3, 4]) );
```

比較には `===` 演算子が用いられる。

###jQuery
なし

#リストをソートする
##Java
```java:
import java.util.Arrays;
import java.util.List;
...

List<Integer> list = Arrays.asList(4, 1, 3, 2);
list.sort(Integer::compare);
System.out.println(list);
```

##Groovy
```groovy:
println( [4, 1, 3, 2].sort() )
```

##JavaScript
###Underscore.js
```js:
var array = _.sortBy([4, 1, 3, 2], function(e) {
    return e;
});

console.log(array);
```

第二引数の関数は、ソートで使用する値を返すように実装する（比較処理（comparator）を実装するわけではない）。

###jQuery
なし。

#リストの中で最小の要素を取得する
各言語、最大の場合は `max` に変わるだけ。

##Java
```java:
import java.util.Arrays;
import java.util.Optional;
...

Optional<Integer> min = Arrays.asList(1, 2, 3, 4).stream().min(Integer::compare);
System.out.println(min.get());
```

##Groovy
```groovy:
println([1, 2, 3, 4].min())
```

##JavaScript
###Underscore.js
```js:
var min = _.min([1, 2, 3, 4]);
console.log(min);
```

###jQuery
なし



#マップの各要素を順次処理する
##Java
```java:
import java.util.HashMap;
import java.util.Map;
...

Map<String, String> map = new HashMap<>();
map.put("hoge", "HOGE");
map.put("fuga", "FUGA");
map.put("piyo", "PIYO");

map.forEach((key, value) -> {
    System.out.println(key + " : " + value);
});
```

##Groovy
```groovy:
[hoge: 'HOGE', fuga: 'FUGA', piyo: 'PIYO'].each {key, value ->
    println "${key} : ${value}"
}
```

##JavaScript
###Underscore.js
```js:
var map = {hoge: 'HOGE', fuga: 'FUGA', piyo: 'PIYO'};

_.each(map, function(value, key, obj) {
    console.log(key + ' : ' + value);
});
```

###jQuery
```js:
var map = {hoge: 'HOGE', fuga: 'FUGA', piyo: 'PIYO'};

$.each(map, function(key, value) {
    console.log(key + ' : ' + value);
});
```

#マップの各エントリーを処理して最終的にリストに変換する
##Java
```java:
import java.util.HashMap;
import java.util.Map;
...

Map<String, String> map = new HashMap<>();
map.put("hoge", "HOGE");
map.put("fuga", "FUGA");
map.put("piyo", "PIYO");

map.entrySet()
   .stream()
   .map(e -> e.getKey() + e.getValue())
   .forEach(System.out::println);
```

##Groovy
```groovy:
[hoge: 'HOGE', fuga: 'FUGA', piyo: 'PIYO']
    .collect {it.key + it.value}
    .each {println it}
```

##JavaScript
###Underscore.js
```js:
var map = {hoge: 'HOGE', fuga: 'UGA', piyo: 'PIYO'};

var array = _.map(map, function(value, key) {
    return key + value;
});

console.log(array);
```

###jQuery
```js:
var map = {hoge: 'HOGE', fuga: 'UGA', piyo: 'PIYO'};

var array = $.map(map, function(value, key) {
    return key + value;
});

console.log(array);
```



#メソッド（関数）名対応表
|Java|Groovy|Underscore.js|jQuery|
|:---|:-----|:------------|:-----|
|forEach|each|each|each|
|filter|findAll|filter|grep|
|-|find|find|-|
|allMatch|every|every|-|
|anyMatch|any|any|-|
|map|collect|map|map|
|reduce|inject|reduce|-|
|flatMap|flatten|flatten|-|
|distinct|unique|uniq|-|
|sort|sort|sortBy|-|
|min|min|min|-|
|max|max|max|-|


#参考
- [Java Streamメモ(Hishidama's Java8 Stream Memo)](http://www.ne.jp/asahi/hishidama/home/tech/java/stream.html)
- [Collection (Groovy JDK)](http://groovy.codehaus.org/groovy-jdk/java/util/Collection.html)
- [Object (Groovy JDK)](http://groovy.codehaus.org/groovy-jdk/java/lang/Object.html)
- [Groovy - JN1015-Collections](http://groovy.codehaus.org/JN1015-Collections)
- [List (Groovy JDK)](http://groovy.codehaus.org/groovy-jdk/java/util/List.html)
- [Utilities - jQuery 日本語リファレンス](http://semooh.jp/jquery/api/utilities/)
- [Utilities | jQuery API Documentation](http://api.jquery.com/category/utilities/)
- [Underscore.js](http://underscorejs.org/#)
- [Java Platform SE 8](http://docs.oracle.com/javase/jp/8/api/)