2010-12-02 14 views
1

Ich sortiere gerade ein Array von Objekten basierend auf einem benutzerdefinierten Kriteriensatz. Die Daten wie folgt aussehen:Vorübergehende Sortierung eines Objekt-Arrays

// Array to Sort 
Object 
    $key = value1 
Object 
    $key = value2 
Object 
    $key = value3 
Object 
    $key = value4 

// Comparison Object 
Sorter 
    $data = array('value1', 'value2', 'value4', 'value3'); 

Ich versuche, die Anzahl der Schleifen zu reduzieren, und dachte es soll ein einfacher/schneller Weg, dies zu tun. Ich möchte keine benutzerdefinierten Werte zu den Objekten selbst hinzufügen, um sie zu sortieren. Der Grundgedanke dabei ist, eine benutzerdefinierte Sortierung aus einem vorherigen Datensatz extrahieren zu können, ohne etwas an den Objekten selbst vornehmen zu müssen.

Ich habe versucht, in die Dokumentation von array_intersects suchen, etc, aber ich konnte keine gute Methode finden, dies zu handhaben ....

Hier ist der Code, den ich habe zur Zeit:

$children = array(
    array('key' => 'value1'), 
    array('key' => 'value2'), 
    array('key' => 'value3'), 
    array('key' => 'value4') 
); 

$comparison = array('value1', 'value2', 'value4', 'value3'); 
$sorter = array(); 

// loop 1 -- create a map   
foreach ($children as &$child) { 
    $sorter[] = array(
     'sort' => array_search($child['key'], $comparison, true), 
     'child' => &$child 
    ); 
} 

// loop 2 -- sort based upon the sort key 
usort($sorter, array($this, 'compare')); 

// loop 3 (ugh -- I think this can be done in 2 loops) 
$output = array(); 
foreach ($sorter as &$item) { 
    $output[] = $item['child']; 
} 

// return 
return $output; 

// sort function 
private function compare(Array $a, Array $b) { 
    if( $a['sort'] == $b['sort']) { return 0 ; } 
    return ($a['sort'] < $b['sort']) ? -1 : 1; 
} 

Antwort

1

Wie darüber?

$children = array(
    array('key' => 'value1'), 
    array('key' => 'value2'), 
    array('key' => 'value3'), 
    array('key' => 'value4') 
); 

// not all values from $children are in there 
$comparison = array('value1', 'value4', 'value3'); 

$ukey = count($comparison); 
$output = array(); 
foreach ($children as $child) { 
    if (($key = array_search($child['key'], $comparison)) !== false) { 
     $output[$key] = $child; 
    } else { 
     // if value is not in $comparison, push it at the end 
     $output[$ukey++] = $child; 
    } 
} 

ksort($output); 
return $output; 

zurückkehrt Dies würde:

Array 
(
    [0] => Array 
     (
      [key] => value1 
     ) 
    [1] => Array 
     (
      [key] => value4 
     ) 
    [2] => Array 
     (
      [key] => value3 
     ) 
    [3] => Array 
     (
      [key] => value2 
     ) 
) 
+0

Dies würde funktionieren, wenn das Vergleichsobjekt immer darin, die Werte des ursprünglichen Arrays hat. Es ist nicht garantiert, dass meins wird - ich würde eine Lösung bevorzugen, wo ausgelassene Werte immer noch enthalten sind. – ansiart

+0

Ok, aber Ihre Lösung berücksichtigt das auch nicht. Was möchten Sie tun, wenn der Wert nicht in '$ comparison' steht? Drück es am Ende? Entfernen Sie es? PS .: In PHP ist ein Array kein Objekt. – netcoder

+0

Wie auch immer, ich aktualisierte meine Antwort, so dass Werte, die nicht in $ Vergleich sind, am Ende geschoben werden. – netcoder

Verwandte Themen