配列(リスト)から特定の条件にマッチする要素のみを取り出すには (array_filter / delete_if / filter / grep / keep_if / partition / reject / select) 2015/03/24
各プログラミング言語での、配列から述語関数にマッチする要素のみを取り出した配列を作成する方法。または述語関数にマッチする要素のみのリストとマッチしない要素のみのリストの2つに分ける方法。
Scala PHP Python Ruby Perl CoffeeScript
Scala 2015/01/15
以下は、フィルター済みのリストを返し、自身は変更しないメソッド。
Signature:
def scala.collection.Seq[A]#filter(p: A => Boolean): Seq[A]
例
val lst = List(1, 2, 3, 4, 5);
val filtered = lst.filter(_ % 2 == 1);
println(filtered);
// => List(1, 3, 5)
以下は、条件にマッチする要素のみのリストと、マッチしない要素のみのリストの2つを返すメソッド。
Signature:
// scala.collection.Seq[A]
def partition(p: A => Boolean): (Seq[A], Seq[A])
例
val lst = List(1, 2, 3, 4, 5);
val (matchList, unmatchList) = lst.partition(_ % 2 == 1);
println(matchList);
// => List(1, 3, 5)
println(unmatchList);
// => List(2, 4)
もし、フィルター済みのリストの要素の数を数えたいだけの場合は、count
メソッドを使える。
Signature:
// scala.collection.Seq[A]
def count(p: A => Boolean): Int
このメソッドで条件にマッチした要素の数を取得できる。
PHP 2016/06/21
array_filter
関数でできる。
$arr = array(1, 2, 3, 4, 5);
$filtered = array_filter($arr, function($elem){
return $elem % 2 == 1;
});
var_export($filtered);
// 出力結果
// array (
// 0 => 1,
// 2 => 3,
// 4 => 5,
// )
キーはそのまま維持されてフィルタリングされるので、上記例のように添字に欠番が生じることもある。
PHPは普通の配列と連想配列が同じものなので、
array_filter
関数は連想配列でも使える。
array_map
関数と引数の順番が違うので、要注意。
array_filter
関数 | PHP Manual
http://php.net/manual/ja/function.array-filter.php
ただし、array_filter
は遅いので、普通に foreach で回しながら新しい配列を作ったほうが速い、という話もある。
PHPで高速オシャレな配列操作を求めて | Qiita
http://qiita.com/Hiraku/items/190443b33ee7a2167ade
Python 2013/10/09
filter
関数を使う例
lst = [10, 20, 30, 40, 50]
print filter((lambda x: x < 30), lst)
# => [10, 20]
リストの内包表記を使う例
lst = [10, 20, 30, 40, 50]
print [x for x in lst if x < 30]
# => [10, 20]
Ruby / JRuby 2015/01/04
Enumerable#select
は条件にマッチする要素のみを抽出した配列を返す。
Enumerable#reject
は逆に条件にマッチしない要素のみを抽出した配列を返す。
Enumerable#partition
は条件にマッチする要素の配列と、マッチしない要素の配列を返す。返り値は配列の配列になる。
いずれも条件はブロックで表現する。
Array
はEnumerable
をインクルードしているので、Array
でもEnumerable
のメソッドを使える。
positive = arr.select {|elem| elem > 0}
positive, negative_or_zero = arr.partition {|elem| elem > 0}
Array#delete_if
や Array#reject!
は reject
と同じで条件にマッチする要素を配列から削除するが、
reject
と違い、配列自身を変更してしまう破壊的なメソッド。
should_be_positive.delete_if {|elem| elem <= 0}
Array#keep_if
や Array#select!
は Array#delete_if
とは逆に条件にマッチしない要素を配列から削除する破壊的なメソッド。
Enumerable#select
| Ruby 2.1 リファレンスマニュアル
http://docs.ruby-lang.org/ja/2.1.0/method/Enumerable/i/find_all.html
Enumerable#reject
| Ruby 2.1 リファレンスマニュアル
http://docs.ruby-lang.org/ja/2.1.0/method/Enumerable/i/reject.html
Enumerable#partition
| Ruby 2.1 リファレンスマニュアル
http://docs.ruby-lang.org/ja/2.1.0/method/Enumerable/i/partition.html
Array#delete_if
, Array#reject!
| Ruby 2.1 リファレンスマニュアル
http://docs.ruby-lang.org/ja/2.1.0/method/Array/i/delete_if.html
Array#keep_if
| Ruby 2.1 リファレンスマニュアル
http://docs.ruby-lang.org/ja/2.1.0/method/Array/i/keep_if.html
Array#select!
| Ruby 2.1 リファレンスマニュアル
http://docs.ruby-lang.org/ja/2.1.0/method/Array/i/select=21.html
Perl 2015/10/17
grep
関数を使う。
grep
はgrep
コマンドと似たイメージだが、行番号を返したりすることはできない。代わりに条件として正規表現以外に任意の述語関数を使える。
奇数のみの新しい配列を作る例
my @arr = (1, 2, 3, 4, 5);
my @newArr = grep { $_ % 2 == 1; } @arr;
print "@newArr";
# => 1 3 5
map
関数と組み合わせて、以下のような書き方もできる。
Scalaだとかのメソッドチェーンとは見た目が逆で右から左に処理される。
my @arr = 1..10;
my @newArr = map { $_ * 2 } grep { $_ % 2 == 1; } @arr;
print "@newArr";
# => 2 6 10 14 18
CoffeeScript 2013/04/19
配列の内包表記
(elem for elem in arr when elemを使った条件式)