2012-05-08 14 views
8

Tengo una matriz de objetos. Me gustaría eliminar los duplicados según el valor de "nombre" en el objeto.Eliminar duplicados de una matriz en función de la propiedad del objeto?

[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" 
    } 

lo tanto, en este caso, ¿Cómo se quita el duplicado objeto "la financiación de campaña" de la matriz. ¿Entonces todo el objeto [2]?

He pasado por un montón de la pregunta de arreglos duplicados de PHP aquí, pero ninguno parecía tratar con los objetos y el filtrado justo fuera de un parámetro.

Respuesta

11

Construya una nueva matriz con las claves existentes y solo el nombre como valor, use array_unique (tenga en cuenta que conserva las claves).

A continuación, elimine todo lo que no está en la matriz exclusiva del original.

Editar: Ejemplo completo:

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); 

de salida:

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 
     ) 

) 

se eliminó el objeto con term_id 15, ya que tenía el mismo nombre que term_id 14.

+0

Esto está cerca, pero necesito el acceso a la "babosa" y "term_id" clave de también. Estoy jugando para ver si puedo resolverlo. –

+0

Tiene ese acceso después, es solo para descubrir qué teclas eliminar. Publicaré un ejemplo completo en un segundo. – ccKep

+0

gracias. funciona muy bien en un problema bastante complejo en el que he estado trabajando durante horas. – byron

1

que estaba buscando una buena respuesta a esto y no pude encontrar una, así que escribí la mía que manejará este caso, y el caso en el que desea quitar el dupe basándose en múltiples propiedades.

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

Aquí está la función genérica:

/** 
* 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; 
} 

Aquí está el uso completo para su caso:

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

que necesitaba lo mismo ... Aquí es lo que hice (trabajo para tanto matriz como objetos, basados ​​en 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

poco fuera de tema, pero estrechamente relacionados: el camino más corto para Dedupe una matriz de objetos con sólo su ejemplo:

/** 
* 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()' es una buena idea! –

Cuestiones relacionadas