PHPは、広く使用されているサーバー側のプログラミング言語であり、 Array_count_values関数が非常に一般的で有用な関数である強力な配列処理機能を提供します。 array_count_values関数の関数は、配列内のすべての要素の発生頻度をカウントすることです。キーが元の配列の要素であり、値が要素の発生数である配列を返します。ただし、オブジェクトを含む配列を扱う場合、予期しない動作に遭遇する可能性があります。これにより、特にオブジェクトの配列に対して、統計結果が不正確になります。
array_count_values関数の基本的な関数は、arrayを繰り返して各要素の発生数をカウントすることであり、結果はキー値ペアの形で返されます。たとえば、単純な配列があるとします。
$array = ['apple', 'banana', 'apple', 'orange', 'banana', 'banana'];
$result = array_count_values($array);
print_r($result);
出力は次のとおりです。
Array
(
[apple] => 2
[banana] => 3
[orange] => 1
)
ご覧のとおり、 array_count_valuesは各要素の発生数を正しくカウントします。
PHPアレイにオブジェクトを保存すると、 array_count_values関数が予想どおりに動作しない場合があります。これは、オブジェクトが参照によって渡されるため、PHPのオブジェクトはメモリアドレスによって比較されるためです(値ではありません)。これは、2つのオブジェクトが同じように見える場合でも、メモリアドレスが異なるため、異なるオブジェクトと見なされることを意味します。
簡単な例を見てみましょう:
class Fruit {
public $name;
public function __construct($name) {
$this->name = $name;
}
}
$apple1 = new Fruit('apple');
$apple2 = new Fruit('apple');
$array = [$apple1, $apple2, $apple1];
$result = array_count_values($array);
print_r($result);
出力の結果は次のとおりです。
Array
(
Object(Fruit)#1 => 2
Object(Fruit)#2 => 1
)
同じ名前の2つのAppleオブジェクトがありますが、それらは2つの異なるインスタンス(つまり、異なるメモリアドレス)であるため、 array_count_valuesはそれらを異なる要素として扱い、個別にカウントします。
array_count_valuesを使用してオブジェクトを含む配列を処理しようとすると、オブジェクトの実際のコンテンツではなく、各オブジェクトのメモリアドレスをカウントします。これは、次の問題につながる可能性があります。
同じコンテンツを持つオブジェクトの複数のインスタンスがある場合、それらは異なる用語としてカウントされ、結果として不正確なカウント結果が得られます。
同じクラスの複数のオブジェクトインスタンスを使用する場合、 array_count_valuesは、これらのオブジェクトのプロパティがまったく同じであっても、それらを同じ要素として扱いません。
オブジェクトを含む配列を正しく処理するために、次の方法を実行できます。
__toStringメソッドを書き直します。
オブジェクトに一意の文字列表現(オブジェクトのプロパティ値など)がある場合、オブジェクトの__toStringメソッドをオーバーライドしてオブジェクトを文字列に変換して、 array_count_valuesを文字列に基づいてカウントできます。
class Fruit {
public $name;
public function __construct($name) {
$this->name = $name;
}
public function __toString() {
return $this->name;
}
}
$apple1 = new Fruit('apple');
$apple2 = new Fruit('apple');
$array = [$apple1, $apple2, $apple1];
$result = array_count_values($array);
print_r($result);
出力の結果は次のとおりです。
Array
(
[apple] => 3
)
これにより、同じ名前のオブジェクトを正しくカウントできます。
__toStringメソッドに依存しない場合は、 Serializeを使用してオブジェクトを文字列に変換してから、カウントにarray_count_valuesを使用できます。
$array = [serialize($apple1), serialize($apple2), serialize($apple1)];
$result = array_count_values($array);
print_r($result);
出力は次のとおりです。
Array
(
[O:6:"Fruit:..."] => 3
)
この方法では、 serializeによってオブジェクトを一意の文字列に変換して、 array_count_valuesが同じオブジェクトの回数を正しく計算できるようにします。
array_count_valuesを使用してオブジェクトを含む配列を処理する場合、 array_count_valuesは、オブジェクトがメモリアドレスによって比較されるため、同じコンテンツでオブジェクトを正しくカウントできない場合があります。この問題は、 __toStringメソッドを上書きするか、 Serializeメソッドを使用して効果的に解決でき、 array_count_valuesはオブジェクト配列内の要素を正しくカウントします。