Rolf B: Array Max Min ermitteln und zusammensetzen

Beitrag lesen

Hallo WernerK,

wenn Du den Index brauchst, ist mein Vorschlag 1 schon mal hinfällig.

Vielleicht sollten wir aber mal die Voraussetzungen klar stellen. $time_arr[$key] ist also basierend auf einer DB-Abfrage entstanden, und in diesem Array sind die Keys irgendwelche IDs in der DB und die Values die Timestamps. Du brauchst zu den modifizierten Timestamps die unveränderten IDs.

Und du fragst, was wäre, wenn die Timestamps nicht aufsteigend aus der DB kämen. Da möchte ich einhaken: Ob etwas aufsteigend aus der DB kommt oder nicht, das hast Du zumeist selbst in der Hand. Die ORDER BY Klausel in einer SQL Abfrage ist kein Hexenwerk. Du würdest ohne ORDER BY beispielsweise dieses DB-Ergebnis bekommen (Time statt Timestamp für kürzeren Text):

Name     Key      Time
Bar       25      17:00
Foo       27      12:00
Foo       28      19:00
Bar       26      04:00
Foo       29      05:00

mit einem ORDER BY Name, Time wäre das

Name     Key      Time
Bar       26      04:00
Bar       22      17:00
Foo       29      05:00
Foo       27      12:00
Foo       28      19:00

D.h. du hättest

$time_arr = ARRAY(
      'Bar' => ARRAY( 26 => '04:00', 22 => '17:00' ),
      'Foo' => ARRAY( 29 => '05:00', 27 => '12:00', 28 => '19:00')
   );

Die Frage ist, ob Dir diese Reihenfolge irgendwo Probleme macht. Wenn Du $time_arr['Foo'] mit einer foreach-Schleife durchläufst, besucht er die Keys 29, 27 und 28, in dieser Reihenfolge. Wenn das für Dich OK ist, kannst Du meinen Vorschlag 2 von oben verwenden und den asort einfach weglassen - das Ergebnis des asort ist ja bereits aus der DB gekommen.

Mein Vorschlag 3 bleibt relevant, falls Du keinen ORDER BY und auch keinen asort machen kannst, d.h. die Einträge in anderer Reihenfolge in den Arrays brauchst. Er muss aber geändert werden, ich hatte übersehen dass Du die Keys für minimalen und maximalen Timestamp brauchst.

function locate_min_max($arr) {
   $minKey = array_key_first($arr);
   $maxKey = $minKey;
   foreach ($arr as $key => $val) {
      if ($val < $arr[$minKey])
         $minKey = $key;
      else if ($val > $arr[$maxKey])
         $maxKey = $i;
   }
   return ARRAY('minKey' => $minKey, 'maxKey' => $maxKey);
}

Die Funktion rufst Du für ein $time_arr[...] auf und bekommst ein Assoziatives Array zurück mit den Schlüsseln für kleinsten und größten Timestamp. Damit kannst Du die Addition/Subtraktion durchführen, und auch den Update in die DB machen.

$minmax = locate_min_max($time_arr[$name]);

$time_arr[$name][$minmax['minKey']] = // 1 Stunde subtrahieren
$time_arr[$name][$minmax['maxKey']] = // 1 Stunde addieren

Du kannst auch auf die Funktion verzichten und den Code darin einfach an die Stelle des Aufrufs kopieren.

$minKey = array_key_first($time_arr[$name]);
$maxKey = $minKey;
foreach ($$time_arr[$name] as $key => $val) {
   if ($val < $time_arr[$name][$minKey])
      $minKey = $key;
   else if ($val > $time_arr[$name][$maxKey])
      $maxKey = $i;
}

$time_arr[$name][$minKey] = // 1 Stunde subtrahieren
$time_arr[$name][$maxKey] = // 1 Stunde addieren

// 1. SQL Update für minKey ausführen
// 2. SQL Update für maxKey ausführen

Wenn Du die Ergebnisse gar nicht im Speicher brauchst, sondern nur in der DB, könnte man auch noch überlegen, es mit reinem SQL zu machen. Ich denke, dass das gehen könnte - aber es könnte einiges an SQL Akrobatik erfordern.

Rolf

--
sumpsi - posui - clusi