【php】配列から、重複している要素、1個しかない要素を探す
問題
ある配列の要素の中から、重複している要素だけを探したり、1個しかない重複していない要素を探したりしたいです。
答え
わかりやすくはないかもしれないけど1行でできなくもなかった。
以下は、array_filterを使った例。
重複した要素を探す
$data = array(1, 2, 2, 3, 4, 4, 5, 7, 10, 20, 10, 4); $res = array_filter(array_count_values($data), function($v){return --$v;}); //PHP5.2 以前の場合 $res = array_filter(array_count_values($data), create_function('$v', 'return --$v;')); array(3) { [2]=> int(2) [4]=> int(3) [10]=> int(2) }
重複してない要素を探す
$data = array(1, 2, 2, 3, 4, 4, 5, 7, 10, 20, 10, 4); $res = array_filter(array_count_values($data), function($v){return !--$v;}); //PHP5.2 以前の場合 $res = array_filter(array_count_values($data), create_function('$v', 'return !--$v;')); array(5) { [1]=> int(1) [3]=> int(1) [5]=> int(1) [7]=> int(1) [20]=> int(1) }
・結果は、キーに値、値に重複した数となります。値の方が欲しいときは、さらに array_keys などする。
・評価する配列内の値の型は考慮していません。数値と文字列の同一値( 2 と “2” 等)がある場合、array_count_valuesによって重複と判断されます。
array_count_valuesで重複値をカウントし、それに対してarray_filterしている。
array_filterのcallbackで –$v してるのは、1(つまり重複してない)の場合は0になってreturnされるのでfalse扱い。2以上(つまり重複してる)の場合は1以上になってtrue扱い。
重複してない要素を探すときは、returnする値を ! して逆転させている。
別解
array_filterやcallbackを使わない版
$data = array(1, 2, 2, 3, 4, 4, 5, 7, 10, 20, 10, 4); //配列の中で1個しかない要素 $res = array_keys(array_count_values($data), 1); var_dump($res); /* array(3) { [1]=> int(2) [4]=> int(4) [8]=> int(10) } */ //配列の中で1個しかない要素じゃないもの = 重複している要素 $res = array_unique(array_diff($data, array_keys(array_count_values($data), 1))); var_dump($res); /* array(5) { [0]=> int(1) [1]=> int(3) [2]=> int(5) [3]=> int(7) [4]=> int(20) } */
コメント