# Doppelten Einträge in mehrdimensionalen Array entfernen



## buzzom (6. September 2012)

Hallo liebe Coder,

ich habe ein Problem mit doppelten Einträgen in einem mehrdimensionalen Array aus einer Datenbankabfrage.

```
print_r($row_set);
```
gibt z.B. folgende Ausgabe (nur ein Ausschnitt, Ausgabe umfasst viele hundert Einträge):


```
Array
(
    [0] => Array
        (
            [value] => Pferde
            [page_id] => 1
            [page_namespace] => 0
            [page_is_redirect] => 0
            [id] => 1
        )

    [1] => Array
        (
            [value] => Esel
            [page_id] => 2
            [page_namespace] => 2
            [page_is_redirect] => 0
            [id] => 2
        )

    [2] => Array
        (
            [value] => Pferde
            [page_id] => 3
            [page_namespace] => 8
            [page_is_redirect] => 0
            [id] => 3
        )
)
```

Nun steht zweimal unter [value] Pferde. Ich möchte im Array jedoch nur noch einmal Pferde zu stehen haben. 

Also so:


```
Array
(
    [0] => Array
        (
            [value] => Pferde
            [page_id] => 1
            [page_namespace] => 0
            [page_is_redirect] => 0
            [id] => 1
        )

    [1] => Array
        (
            [value] => Esel
            [page_id] => 2
            [page_namespace] => 2
            [page_is_redirect] => 0
            [id] => 2
        )
)
```

array_unique() funktioniert ja leider nicht bei mehrdimensionalen Arrays und andere Codeansätze habe ich zwar im Netz gefunden, aber leider bekomme ich es nicht hin. Ich würde mich daher über Hilfe sehr freuen.

Rückgabewert des php Script ist dann übrigens noch 
	
	
	



```
echo json_encode($row_set);
```

Vielen lieben Dank
buzzi


----------



## Yaslaw (6. September 2012)

Welche Pferde hättest du denn gerne? die mit der ID=3 oder mit der id=1?


----------



## buzzom (6. September 2012)

Ist Egal eigentlich. Hauptsache einmal Pferde. ;-) Dann wohl immer den ersten Wert bei doppelten Einträgen.


----------



## ComFreek (6. September 2012)

Eventuell gibt es einen eleganteren Weg, aber dies sollte funktionieren:

```
$result = array();
$values = array();

foreach ($row_set as $entry) {
	$val = $entry['value'];
	if ( !isset($values[$val]) ) {
		$result[] = $entry;
		$values[$val] = true;
	}
}
```
Siehe Live-Demo: http://codepad.org/Hq4KASAC


----------



## Yaslaw (6. September 2012)

Oder du verwendest die Funktion die ich vor langer Zeit mal geschrieben habe
array_unique_by_subitem()


```
<?php

//Testdaten
$items[0] = array('value' => 'Pferde', 'page_id' => 1, 'page_namespace' => 0, 'page_is_redirect' => 0, 'id' => 1);
$items[1] = array('value' => 'Esel', 'page_id' => 2, 'page_namespace' => 2, 'page_is_redirect' => 0, 'id' => 2);
$items[2] = array('value' => 'Pferde', 'page_id' => 3, 'page_namespace' => 8, 'page_is_redirect' => 0, 'id' => 3);

//Funktion array_unique_by_subitem() anwenden und Resultat ausgeben
print_r(array_unique_by_subitem($items, 'value'));


/**
 * array_unique über ein Element eines Array
 * @param     Array<Key => Array<Node>>   Ein mehrstufiger Array
 * @param     String
 * @param     Integer
 * @return    Array<Key => Array<Node>>  
 */
function array_unique_by_subitem($array, $key, $sort_flags  = SORT_STRING){
    $items = array();
    // Die Subeitems auslesen
    foreach($array as $index => $item) $items[$index] = $item[$key];
    //Die Subitems mit array_unique bearbeiten
    $uniqueItems = array_unique($items, $sort_flags);
    //Der eigentliche Array über den Key mit den selektierten Subitems abgleichen
    return array_intersect_key($array, $uniqueItems);
}
?>
```


```
Array
(
    [0] => Array
        (
            [value] => Pferde
            [page_id] => 1
            [page_namespace] => 0
            [page_is_redirect] => 0
            [id] => 1
        )

    [1] => Array
        (
            [value] => Esel
            [page_id] => 2
            [page_namespace] => 2
            [page_is_redirect] => 0
            [id] => 2
        )

)
```

Auf codepad.viper-7.com: http://codepad.viper-7.com/HZZaNq


----------



## buzzom (6. September 2012)

Vielen Dank euch beiden. Deine function array_unique_by_subitem() funktioniert wie gewünscht, yaslow. ComFreeks Lösung leider nicht. Warum weiss ich jedoch auch nicht. Trotzdem auch dir, herzlichen dank für die Hilfe.

Allerdings gibt es noch ein Problem:

Am Ende wird ja das Array noch via echo json_encode($row_set); ausgegeben, sodass es via JQuery genutzt werden kann. Vor der Bearbeitung durch deine function array_unique_by_subitem() sah das echo json_encode($row_set); folgendermaßen aus:

Ausschnitt:

```
[{"value":"Pferde","page_id":"1","page_namespace":"0","page_is_redirect":"0","id":1},{"value":"Esel","page_id":"2","page_namespace":"2","page_is_redirect":"0","id":2}
```

Hier funktioniert die jQuery Abfrage! Leider aber mit den doppelten Einträgen...

Nach der erfolgreichen Löschung der doppelten Einträge durch die Funktion jedoch:

```
{"0":{"value":"Pferde","page_id":"1","page_namespace":"0","page_is_redirect":"0","id":1},"1":{"value":"Esel","page_id":"2","page_namespace":"2","page_is_redirect":"0","id":2}
```

Damit funktioniert dann leider nicht mehr die jQuery Abfrage. Irgendwie ist die Formatierung des Arrays anders.

Mein Code soweit:


```
$row_set = array_unique_by_subitem($row_set, 'value');
echo json_encode($row_set);
```

Vielleicht kann man die Doubletten ja auch gleich bei der MySql Abfrage ausklammern?
Meine bisherige Abfrage geht so:

```
SELECT page_title as value, page_id FROM page WHERE page_title LIKE '%".$term."%'
```


Habt Ihr einen Rat?

Vielen lieben Dank schonmal soweit.


----------



## ComFreek (6. September 2012)

Du könntest DISTINCT nutzen:

```
SELECT DISTINCT page_title as value, page_id FROM page WHERE page_title LIKE '%***%'
```


Gibt es bei meiner Lösung irgendwelche Fehler (setz mal [phpf]error_reporting[/phpf] auf E_ALL)? Order benutzt du schon irgendeinen Variablennamen, den ich auch hatte?

Zum "Problem" von yaslaw's Lösung:
Das Root-Element ist nun ein Objekt und kein Array. Im Prinzip sind den einzelnen Arrayelementen nur die Indexzahlen zugeordnet.

Folgendes sollte das Problem lösen:

```
$objectRes = array_unique_by_subitem($items, 'value');
$arrayRes = array()

foreach ($objectRes as $entry) {
  $arrayRes[] = $entry;
}
```


----------



## Sebastian Schmidt (7. September 2012)

Ich würde dir auch raten direkt richtig zu selektieren, statt deinen Quellcode unnötig aufzublähen was zu Rechenzeit führt. Stimme da ComFreek vollkommen zu.


----------

