php array_filter: 配列をフィルタリングする

  • ---

    LINEで送る
  • -

    ブックマーク
  • -

    pocket
  • -

    rss
イラストACの画像をもとに加工しています。

フィルタリングは『ろ過』のことでデータを選別します。ある条件で排除することが多いですね?

PHPもフィルタリングができます。array_filter()です。

array_filter()の使い方をサンプルプログラムで分かりやすく説明します。

フィルタリングとは?

Webではよく『フィルタリング』ということばを聞きますよね?

URLフィルタリング

IPフィルタリング

etc...

これらは

ある条件のものを排除

します。

フィルタリングはデータを選別する・分類するという大きな意味がありますが、どちらかといえば特定のデータを消す・排除することが多いです。

コールバック関数とはなにか?

コールバック関数は

関数の引数で渡す関数

です。

array_filter($array, function($value) {
    return false;
});

ここでは無名関数を使ってます。

無名関数は名前がない関数で、変数に入れられる関数のこと。

-> PHP公式ドキュメント - 無名関数 -

関数は

この処理をして結果をちょうだい。

と処理を任せてしまうことですが、コールバック関数は

この関数を使って処理してよ。最終結果だけちょうだい。

と関数(コールバック)は指定しますが、処理の実行と結果の使い道はコールバック関数を引き受けた関数が行ないます。

コールバック関数
<?php

/**
 * callback function
 */
function cb_sample() {
  return "hello";
}

/**
 * function
 */
function sub_sample( $cb ) {
  return $cb() . " world!";
}

echo sub_sample( 'cb_sample' );
実行結果
hello world!

PHPのフィルタリングでは

削除するデータの条件を決める

仕事をコールバック関数がします。

コールバック関数はフィルタリングのルールを書く。

array_filter()のコールバック関数は、boolean(true, false)を返さないといけません。

戻り値データはどうなる?
false削除
true残す

フィルタリングしてみよう!

いろんなフィルタリングをしてみましょう。

基本的なことだけ行ないます。あとは応用していろいろ試してみてください。

偶数・奇数

偶数をはじくフィルタリング、奇数をはじくフィルタリングをします。

サンプルコードです。

<?php

$array = [1,2,3,4,5,6,7,8,9,10];

/**
 * odd callback
 */
function cb_odd($value) {
    return $value & 1;
}

/**
 * even callback
 */
function cb_even($value) {
    return !($value & 1);
}

var_dump(array_filter($array, 'cb_odd'));
var_dump(array_filter($array, 'cb_even'));
array(5) {
  [0]=>
  int(1)
  [2]=>
  int(3)
  [4]=>
  int(5)
  [6]=>
  int(7)
  [8]=>
  int(9)
}
array(5) {
  [1]=>
  int(2)
  [3]=>
  int(4)
  [5]=>
  int(6)
  [7]=>
  int(8)
  [9]=>
  int(10)
}

いろいろな計算式をコールバック関数に入れれば、計算結果でフィルタリングできます。

文字列をフィルタリングする

'abc'が含まれる文字列をフィルタリングするサンプルです。

'abc'が含むものを抽出・削除してみましょう。

<?php

$array = ['abc','bcd','zzzabc','abczzz', 'zzabczz', 'aabbcc',];

/**
 * take out callback
 */
function cb_take_out($value) {
    if(strpos($value, 'abc') === false) {
        return false;
    } else {
        return true;
    }
}

/**
 * delete callback
 */
function cb_delete($value) {
    if(strpos($value, 'abc') === false) {
        return true;
    } else {
        return false;
    }
}

var_dump(array_filter($array, 'cb_take_out'));
var_dump(array_filter($array, 'cb_delete'));
array(4) {
  [0]=>
  string(3) "abc"
  [2]=>
  string(6) "zzzabc"
  [3]=>
  string(6) "abczzz"
  [4]=>
  string(7) "zzabczz"
}
array(2) {
  [1]=>
  string(3) "bcd"
  [5]=>
  string(6) "aabbcc"
}

正規表現を使った文字列検索をすればいろんなことができそうですね?

空要素を削除する

array_filterには、空要素の削除が用意されています。

コールバックなしで実行

します。

<?php

$array = ['abc','','0','1',0, 1,[1,2,3],[],null];

var_dump(array_filter($array));
array(4) {
  [0]=>
  string(3) "abc"
  [3]=>
  string(1) "1"
  [5]=>
  int(1)
  [6]=>
  array(3) {
    [0]=>
    int(1)
    [1]=>
    int(2)
    [2]=>
    int(3)
  }
}

削除の条件は

empty()

と同じです。

この処理は完ぺきではないので注意が必要です。

'0'

0

が消えます。

また、コールバック関数にstrlen()を使う方法をよく見ますがこれも問題があります。

このあたりはまとめたのでそちらを見て下さい。

-> 空要素の削除にarray_filter()を使うのはやめよう

クラスをフィルタリングする

特定のクラスを抽出・削除します。

<?php

class TEST1 {}
class Test1_1 extends TEST1 {}
class Test1_2 extends TEST1 {}
class Test1_3 extends TEST1 {}
class TEST2 {}
class TEST3 {}

$array = [new TEST1(),new TEST1_1(),new TEST1_2(),new TEST1_3(), new TEST2(), new TEST3(),];

/**
 * take out callback
 */
function cb_take_out($value) {
    return ! ($value instanceof TEST1);
}

/**
 * delete callback
 */
function cb_delete($value) {
    return $value instanceof TEST1;
}

var_dump(array_filter($array, 'cb_take_out'));
var_dump(array_filter($array, 'cb_delete'));
array(2) {
  [4]=>
  object(TEST2)#5 (0) {
  }
  [5]=>
  object(TEST3)#6 (0) {
  }
}
array(4) {
  [0]=>
  object(TEST1)#1 (0) {
  }
  [1]=>
  object(Test1_1)#2 (0) {
  }
  [2]=>
  object(Test1_2)#3 (0) {
  }
  [3]=>
  object(Test1_3)#4 (0) {
  }
}

サンプルのように親クラスを指定して、子クラスもろともフィルタリングできます。

もちろん子クラスだけもできます。くわしくは公式ドキュメントを見てください。

-> PHP公式ドキュメント - instanceof  -

連想配列のフィルタリング

ここまでのフィルタリングは、連想配列をパラメータにわたしても同じ結果になります。

こんどは、連想配列のキーを使う方法をご紹介します。

array_filter()の第3パラメータ(flag)を指定するだけです。

flagcallbackの引数
ARRAY_FILTER_USE_KEYキーだけ
ARRAY_FILTER_USE_BOTHキー,値
なし値だけ
<?php

$array = ['a' => 1,'b' => 2,'c' => 3,'d' => 1,];

/**
 * take out callback (key only)
 */
function cb_take_out_key($key) {
    if ( $key === 'a' ) {
        return true;
    } else {
        return false;
    }
}

/**
 * delete callback (key only)
 */
function cb_delete_key($key) {
    if ( $key === 'a' ) {
        return false;
    } else {
        return true;
    }
}

/**
 * take out callback (value, key)
 */
function cb_take_out_both($value, $key) {
    if ( $value === 1 && $key === 'd' ) {
        return true;
    } else {
        return false;
    }
}

/**
 * delete callback (value, key)
 */
function cb_delete_both($value, $key) {
    if ( $value === 1 && $key === 'd' ) {
        return false;
    } else {
        return true;
    }
}

var_dump(array_filter($array, 'cb_take_out_key', ARRAY_FILTER_USE_KEY ));
var_dump(array_filter($array, 'cb_delete_key', ARRAY_FILTER_USE_KEY ));
var_dump(array_filter($array, 'cb_take_out_both', ARRAY_FILTER_USE_BOTH ));
var_dump(array_filter($array, 'cb_delete_both', ARRAY_FILTER_USE_BOTH ));
array(1) {
  ["a"]=>
  int(1)
}
array(3) {
  ["b"]=>
  int(2)
  ["c"]=>
  int(3)
  ["d"]=>
  int(1)
}
array(1) {
  ["d"]=>
  int(1)
}
array(3) {
  ["a"]=>
  int(1)
  ["b"]=>
  int(2)
  ["c"]=>
  int(3)
}

コールバックのパラメータの順番は決まっています。

(値, キー)

まちがえないようにしましょう。

まとめ

array_filter()は、コールバックに計算式や文字列検索、正規表現をつかうとたくさんのフィルタリングができます。

ただし、問題点もあります。

空要素削除が危ない。

多次元配列に対応できない。

このへんに注意しながら使わないといけません。

-> array_filter()の問題点を解決する

SNSでも記事を配信しています。
コメントを残す

*

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください

top
この記事を気に入ったらぜひシェアも!!