array_unique() で小ハマリ

PHPの関数 array_unique() で小ハマリしたのでメモ。

array_unique() は、配列から重複する要素を削除する関数。

たとえば、こんなプログラム。

$list = array('A', 'B', 'A', 'C');
$list = array_unique($list);
for ($cnt = 0; $cnt < count($list); $cnt++)
{
print($list[$cnt] . "\n");
}

このプログラムは、「A」「B」「A」「C」という配列から、array_unique() によって、重複する「A」の余分な要素を取り除き、「A」「B」「C」という配列にするプログラムである。

このプログラムにおける、期待する実行結果は、こうである。

A
B
C

ところが、実際にプログラムを実行すると、この様に出力される。

A
B

最後の要素「C」が出力されない。
なぜだ。

実行結果だけを見ると、count($list) の値が「2」であるように見える。
確認してみよう。

$list = array('A', 'B', 'A', 'C');
$list = array_unique($list);
print(sprintf("===%d===\n", count($list))); // ★追加★
for ($cnt = 0; $cnt < count($list); $cnt++)
{
print($list[$cnt] . "\n");
}

実行してみると…

===3===
A
B

count($list) の値は「3」なのに、最後の要素が出力されない。
なぜだ。

var_dump() で配列の内容を一覧してみよう。
$list を初期化した後と、array_unique() を通した後に var_dump() を入れてみる。

$list = array('A', 'B', 'A', 'C');
var_dump($list); // ★追加★
$list = array_unique($list);
var_dump($list); // ★追加★
for ($cnt = 0; $cnt < count($list); $cnt++)
{
print($list[$cnt] . "\n");
}

実行してみると…

array(4) {
[0]=>
string(1) "A"
[1]=>
string(1) "B"
[2]=>
string(1) "A"
[3]=>
string(1) "C"

}
array(3) {
[0]=>
string(1) "A"
[1]=>
string(1) "B"
[3]=>
string(1) "C"

}
A
B

なるほど、array_unique() を通した後は、重複している要素番号[2]が抜けて、 [0][1][3] と飛んだ状態で格納されている。
要素数(つまり count($list))は「3」なので、for は [0][1][2] でループするのだけれど、最後の要素の添え字は [3] だから出力されないのか。
おそらく、[2] は null なのだな。

確認してみよう。

$list = array('A', 'B', 'A', 'C');
$list = array_unique($list);
for ($cnt = 0; $cnt < count($list); $cnt++)
{
if ($list[$cnt] == null) // ★追加★
{
print("NULL!\n");
}
print($list[$cnt] . "\n");

}

実行してみる。

A
B
NULL!

では、array_unique() を通した後の配列を正しくループさせるにはどうしたらいいのだろう。
sort() を通して配列を並べ替えたらどうだろうか。

$list = array('A', 'B', 'A', 'C');
$list = array_unique($list);
sort($list); // ★追加★
for ($cnt = 0; $cnt < count($list); $cnt++)
{
print($list[$cnt] . "\n");
}

できた!

A
B
C

しかし、これでは配列がソートされてしまう。ソートしたくない場合はどうしたらいいのだろうか。
array_系の関数をざっと見てみる... これか、array_merge() を使用して、1個の配列だけをマージしてみたらどうか。
やってみよう。

$list = array('A', 'B', 'A', 'C');
$list = array_unique($list);
$list = array_merge($list); // ★追加★
for ($cnt = 0; $cnt < count($list); $cnt++)
{
print($list[$cnt] . "\n");
}

できた!

A
B
C

もっといいやり方があるような気がするのだが、とりあえず、これでヨシとしよう。
なかなか奥が深い。

広告

トラックバック 
〔https://blog2.zunbe.com/wp/wp-trackback.php?p=10390〕

    トラックバックはありません。

コメント

    コメントはありません。

コメントしてください

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です


広告

まとめページ

取得した資格
登った山

広告

サイト内検索

WordPress

最近のコメント

広告

RSS

RSS 記事
RSS コメント
Server offered by
有限会社パテンティックソフトウェア
Profile for zunbe