$array = array(1, '1a', '1');
var_export(array_unique($array, SORT_REGULAR));
- 結果:配列(0 => 1、2 => '1')
- PHPマニュアルの場合:SORT_REGULAR-アイテムを通常どおりに比較します(タイプは変更しないでください)。
この背後にあるロジックは何ですか?「1a」が除外される理由または方法は?
$array = array(1, '1a', '1');
var_export(array_unique($array, SORT_REGULAR));
この背後にあるロジックは何ですか?「1a」が除外される理由または方法は?
これはarray_unique
、最初に値を文字列として並べ替え、次に並べ替えられた配列を反復処理し、結果からそれに等しいと比較されるすべての連続する値を除外することで機能するために発生します。
上記の「同等の比較」の比較関数は、2番目のパラメーターに従って選択されます。これSORT_REGULAR
は、の同等性チェックと同じ==
です。
この振る舞いは、多くの落とし穴を引き起こします。ソートはクイックソートであるため、不安定です。1
したがって、両方を含み、どちら'1'
が結果の最初になるかを保証するものではない配列をソートします。これは、array_unique
場合によっては任意に「優先」するように見える場合が1
あることを意味し'1'
ます。
ただし、狂気は続きます。ソートが生成された場合は[1, '1', '1a']
結果に含まれず(等しいと比較されます)、ソートが生成された場合は含まれます(文字列とは比較されません)。'1a'
1
['1', 1, '1a']
'1'
もう少し技術的になりたい場合は、ソースを参照してください。
PHP_SORT_REGULAR
フラグは、標準の比較演算子()にフォールバックするように指示するarray_unique
だけ==
です。
array_unique
これは、次を使用するソースで確認できますphp_set_compare_func
。
static void php_set_compare_func(int sort_type TSRMLS_DC) /* {{{ */
{
switch (sort_type & ~PHP_SORT_FLAG_CASE) {
...
case PHP_SORT_REGULAR:
default:
ARRAYG(compare_func) = compare_function;
break;
}
標準の比較関数はどこcompare_func
にありますか。
それはおそらく何よりもドキュメントのバグです。ドキュメントのコメントは少し誤解を招く可能性があります。
...(文字列)$ elem1 ===(文字列)$elem2の場合にのみ等しい
両方の値が文字列にキャストされる場合、は不要ですが、型比較===
を行うという仮定につながります。SORT_REGULAR