2012-05-08 17 views
8

Mam tablicę obiektów. Chciałbym usunąć duplikaty na podstawie wartości "name" w obiekcie.Usunąć duplikaty z tablicy na podstawie właściwości obiektu?

[0]=> 
    object(stdClass)#337 (9) { 
    ["term_id"]=> 
    string(2) "23" 
    ["name"]=> 
    string(12) "Assasination" 
    ["slug"]=> 
    string(12) "assasination" 
    } 
    [1]=> 
    object(stdClass)#44 (9) { 
    ["term_id"]=> 
    string(2) "14" 
    ["name"]=> 
    string(16) "Campaign Finance" 
    ["slug"]=> 
    string(16) "campaign-finance" 
    } 
    [2]=> 
    object(stdClass)#298 (9) { 
    ["term_id"]=> 
    string(2) "15" 
    ["name"]=> 
    string(16) "Campaign Finance" 
    ["slug"]=> 
    string(49) "campaign-finance-good-government-political-reform" 
    } 

W takim przypadku w jaki sposób usunąć zduplikowany obiekt "Kampania finansowa" z tablicy. A więc cały obiekt [2]?

Przeszedłem przez kilka pytań z duplikatu PHP tutaj, ale żaden nie zajmował się obiektami i filtrowanie tylko jednego parametru.

Odpowiedz

11

Utwórz nową tablicę za pomocą istniejących kluczy i po prostu nazwę jako wartość, użyj array_unique (pamiętaj, że zachowuje klucze).

Następnie usuń wszystko, czego nie ma w unikatowej tablicy z oryginalnego klucza.

Edit: Kompletny przykład:

class my_obj 
{ 
     public $term_id; 
     public $name; 
     public $slug; 

     public function __construct($i, $n, $s) 
     { 
       $this->term_id = $i; 
       $this->name = $n; 
       $this->slug = $s; 
     } 
} 

$objA = new my_obj(23, "Assasination", "assasination"); 
$objB = new my_obj(14, "Campaign Finance", "campaign-finance"); 
$objC = new my_obj(15, "Campaign Finance", "campaign-finance-good-government-political-reform"); 

$array = array($objA, $objB, $objC); 

echo "Original array:\n"; 
print_r($array); 

/** Answer Code begins here **/ 

// Build temporary array for array_unique 
$tmp = array(); 
foreach($array as $k => $v) 
    $tmp[$k] = $v->name; 

// Find duplicates in temporary array 
$tmp = array_unique($tmp); 

// Remove the duplicates from original array 
foreach($array as $k => $v) 
{ 
    if (!array_key_exists($k, $tmp)) 
     unset($array[$k]); 
} 

/** Answer Code ends here **/ 

echo "After removing duplicates\n"; 
print_r($array); 

wyjściowa:

Original array: 
Array 
(
    [0] => my_obj Object 
     (
      [term_id] => 23 
      [name] => Assasination 
      [slug] => assasination 
     ) 

    [1] => my_obj Object 
     (
      [term_id] => 14 
      [name] => Campaign Finance 
      [slug] => campaign-finance 
     ) 

    [2] => my_obj Object 
     (
      [term_id] => 15 
      [name] => Campaign Finance 
      [slug] => campaign-finance-good-government-political-reform 
     ) 

) 
After removing duplicates 
Array 
(
    [0] => my_obj Object 
     (
      [term_id] => 23 
      [name] => Assasination 
      [slug] => assasination 
     ) 

    [1] => my_obj Object 
     (
      [term_id] => 14 
      [name] => Campaign Finance 
      [slug] => campaign-finance 
     ) 

) 

Obiekt z term_id 15 został usunięty, ponieważ miała taką samą nazwę jak term_id 14.

+0

Jest blisko, ale muszę dostęp do „ślimaka” i „term_id” klucz użytkownika także. Bawię się, żeby sprawdzić, czy uda mi się to rozgryźć. –

+0

Masz ten dostęp później, tylko po to, aby dowiedzieć się, które klucze usunąć. Opublikuję pełny przykład w ciągu sekundy. – ccKep

+0

dziękuję. działa świetnie na dość złożonym problemie, nad którym pracuję od wielu godzin. – byron

1

szukałem Dobra odpowiedź na to pytanie i nie można go znaleźć, więc napisałem własną, która zajmie się tym przypadkiem, oraz przypadek, w którym chcesz usunąć duplikat na podstawie wielu właściwości.

$array = DeDupeArrayOfObjectsByProps($array, ['name']); 

Oto funkcja ogólna:

/** 
* Iterates over the array of objects and looks for matching property values. 
* If a match is found the later object is removed from the array, which is returned 
* @param array $objects The objects to iterate over 
* @param array $props  Array of the properties to dedupe on. 
* If more than one property is specified then all properties must match for it to be deduped. 
* @return array 
*/ 
public function DeDupeArrayOfObjectsByProps($objects, $props) { 
    if (empty($objects) || empty($props)) 
     return $objects; 
    $results = array(); 
    foreach ($objects as $object) { 
     $matched = false; 
     foreach ($results as $result) { 
      $matchs = 0; 
      foreach ($props as $prop) { 
       if ($object->$prop == $result->$prop) 
        $matchs++; 
      } 
      if ($matchs == count($props)) { 
       $matched = true; 
       break; 
      } 

     } 
     if (!$matched) 
      $results[] = $object; 
    } 
    return $results; 
} 

Oto pełne wykorzystanie w Twoim przypadku:

class my_obj { 
    public $term_id; 
    public $name; 
    public $slug; 

    public function __construct($i, $n, $s) { 
     $this->term_id = $i; 
     $this->name = $n; 
     $this->slug = $s; 
    } 
} 

$objA = new my_obj(23, "Assasination", "assasination"); 
$objB = new my_obj(14, "Campaign Finance", "campaign-finance"); 
$objC = new my_obj(15, "Campaign Finance", "campaign-finance-good-government-political-reform"); 
$array = array($objA, $objB, $objC); 

$array = DeDupeArrayOfObjectsByProps($array, ['name']); 
var_dump($array); 
1

Musiałem to samo ... Oto co zrobiłem (praca dla zarówno tablica jak i obiekty, oparte na this post)

function my_array_unique_by_subkey($array,$subkey){ 

    $temp = array(); 

    $unique = array_filter($array, function ($v) use (&$temp,$subkey) { 

     if (is_object($v)) $v = (array)$v; 

     if (!array_key_exists($subkey,$v)) return false; 

     if (in_array($v[$subkey], $temp)) { 
      return false; 
     } else { 
      array_push($temp, $v[$subkey]); 
      return true; 
     } 
    }); 

    return $unique; 
} 
0

Nieco off-topic, ale ściśle związane: najkrótsza droga do DeDupe tablicę obiektów tylko przez ich przykład:

/** 
* The array must NOT contain scalars. 
* 
* @param mixed[] $objects 
* @return mixed[] 
*/ 
public static function arrayUniqueForObjects(array $objects): array 
{ 
    $deDuplicatedArray = []; 

    foreach ($objects as $object) { 
     $deDuplicatedArray[spl_object_hash($object)] = $object; 
    } 

    return array_values($deDuplicatedArray); 
} 
+0

'spl_object_hash()' jest dobrym pomysłem !!! –

Powiązane problemy