SOFTELメモ Developer's blog

会社概要 ブログ 調査依頼 採用情報 ...
技術者募集中

【php】配列から、重複している要素、1個しかない要素を探す

問題

ある配列の要素の中から、重複している要素だけを探したり、1個しかない重複していない要素を探したりしたいです。

php

答え

わかりやすくはないかもしれないけど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)
}
*/

関連するメモ

コメント