0

同じ名前のオブジェクトの配列から要素を削除するにはどうすればよいですか? 以下の場合、名前が同じなので要素0と要素2を削除したい。すべてのケースをループできると考えましたが、それは無駄に思えます。

array(1) { 
 [0]=> object(stdClass)#268 (3) { 
         ["term_id"]=> string(3) "486" 
         ["name"]=> string(4) "2012" 
         ["count"]=> string(2) "40"
 } 
 [1]=> object(stdClass)#271 (3) { 
         ["term_id"]=> string(3) "488" 
         ["name"]=> string(8) "One more"
         ["count"]=> string(2) "20"  
 } 
 [2]=> object(stdClass)#275 (3) { 
         ["term_id"]=> string(3) "512" 
         ["name"]=> string(8) "2012"
         ["count"]=> string(2) "50"  
 } 
4

3 に答える 3

2

配列をループして、各名前が表示される回数を計算できます。次に、 array_filterを使用して、複数回出現する要素をフィルターで除外します。これは、単純な場合と比較して、平均実行時の複雑さO(n)(アレイを想定)になります。O(1)O(n^2)

コード:

$counter = array();
foreach($array as $val) {
  $n = $val->name;
  $counter[$n] = (!isset($counter[$n])) ? 1 : 2;
}
$result = array_filter(
            $array,
            function ($item) use ($counter) { return $counter[$item->name] == 1; }
          );

5.3より前のPHPバージョンではクロージャを使用できないため、その場合は、コードを次のように変更します。

$counter = array();
foreach($array as $val) {
  $n = $val->name;
  $counter[$n] = (!isset($counter[$n])) ? 1 : 2;
}

function my_filter($item) {
    global $counter;
    return $counter[$item->name] == 1;
}
$result = array_filter(
            $array,
            'my_filter'
          );

オーバーヘッドが発生するため、これは実際には大規模なアレイでのみ役立つことに注意してください。また、何が行われているのか理解していないと読みづらいかもしれません。小さな配列(数百要素程度)の場合は、単純な2次時間ループアプローチを使用することをお勧めします。

于 2012-04-27T17:44:15.010 に答える
2

それが変更可能なクラスのオブジェクトである場合は、メソッドにプロパティを__toString()返させて使用することができます:namearray_unique()

(文字列) $elem1 === (文字列) $elem2 の場合に限り、2 つの要素は等しいと見なされます。つまり、文字列表現が同じ場合です。最初の要素が使用されます。

于 2012-04-27T17:39:25.503 に答える
0
$result = array_filter(
  $array,
  function ($item) use ($name) { return $item->name != $name; }
);

これはまさに、あなたが言及した「すべてのケースのループ」であることに注意してください。すべての項目をチェックしたい場合は、他に解決策はありません。

于 2012-04-27T17:37:19.380 に答える