2016-04-11 21 views
1

Mir ist klar, es gibt eine Reihe von Fragen über multidimensionale Arrays und foreach Schleifen, und ich habe Stunden damit verbracht, sie zu lesen und zu versuchen, meine eigene Schleife zu arbeiten - ohne Erfolg. Wenn die Lösung ein Duplikat ist, werde ich meine Frage entfernen (oder einen Link zu einem anderen, wenn das bevorzugt wird).Mehrdimensionale Array-Schleife mit Array-Suche

nun die Herausforderung:

  • eine Reihe von zurück MYSQL Ergebnissen. Die Ergebnisse stammen aus mehreren verknüpften Tabellen in einem assoziativen Array. Jetzt muss ich es in das multidimensionale Array konvertieren, das ich brauche.
  • Ich habe das meiste davon funktioniert, aber mein Problem ist das Durchschleifen und Hinzufügen neuer Elemente an der richtigen Stelle im Array.

Hier einige Code:

//example of how array is setup in the way I want, this part works. 
foreach($results as $i => $a): 

    //some other code is here, see below. 

    $items[$i] = [ 
     "id" => $a['id'], 
     "itemid" => $a['itemid'], 
     "name" => $a['name'], 
     "def" => $a['def'], 
     "class" => $a['class'], 
     "timeline" => $a['timeline'], 
     "files" => [ 
      [0] => [ 
       "id" => $a['fileid'], 
       "name" => $a['filename'], 
       "path" => $a['filepath'], 
       "type" => $a['filetype'] 
      ] 
     ], 
     "tags" => [ 
      [0] => [ 
       "id" => $a['tagid'], 
       "name" => $a['tagname'] 
      ] 
     ] 
    ]; 
endforeach; 

dann auf die ‚Tags‘ oder ‚Dateien‘, um nur eine Reihe von Möglichkeiten, um eine Schleife durch, um hinzuzufügen, ich habe versucht, wenn das Element ‚id‘ ist das gleiche wie das letzte. Hier ist der aktuelle Code in meinem Lektor, nicht funktioniert:

//inside foreach loop, before above code 
if($items[$i-1]['id'] == $a['id']): 
    //it is the same item, works to here. 
    if(in_array($a['filename'], $items[$i-1], FALSE)): 
     //add to files array for last item 
     $items[$i-1]['files'][] = [ 
      "id" => $a['fileid'], 
      "name" => $a['filename'], 
      "path" => $a['filepath'], 
      "type" => $a['filetype'] 
     ]; 
    elseif(in_array($a['tagname'], $items[$i-1], FALSE)): 
     //add to tags array for last item 
     $items[$i-1]['tags'][] = [ 
      "id" => $a['tagid'], 
      "name" => $a['tagname'] 
     ]; 
    endif; 
else:// else it does the code above 

Wie Sie sehen können, mein letzter Versuch war zu verwenden in_array, die ich jetzt erkennen, nicht auf mehrdimensionale Arrays funktioniert. Mein Problem ist, dass ich nicht herausfinden kann, ob es eine neue Datei oder einen neuen Tag für den gleichen Artikel gibt.

Letztendlich möchte ich eine Reihe von 'Elementen', die mehrere 'Dateien' und 'Tags' haben. Ich gehe zu json_encode und benutze es danach mit JS.

Irgendwelche Ratschläge, wie man das funktioniert oder es optimiert, würde sehr geschätzt werden.

P.S. Wie ich oben erwähnt habe, weiß ich, dass diese Frage schon einmal gestellt wurde - obwohl ich nicht in der Lage war, ihre Lösungen für mich arbeiten zu lassen. Ich werde diese Frage entfernen, wenn die Lösung ein Duplikat ist (wie in, es ist nicht wirklich hilfreich für andere). Danke für jede Hilfe, es wird sehr geschätzt!

+0

Was ist Ihre PHP-Version? Bei PHP> = 5.5 können Sie ['array_column'] (http://php.net/manual/en/function.array-column.php) verwenden:' in_array ($ a ['filename'], array_column ($ items [$ i-1] ['files'], 'name')) ' – fusion3k

+0

Danke für den Tipp @ fusion3k. Ich lese die Dokumente zu dieser Funktion und versuche es. – turnfire

Antwort

0

Verwenden Sie keine "autoinkrementierenden" Array-Indizes, da diese leicht durcheinander geraten. Verwenden Sie Ihre Datenbank-ID, da es schon da ist:

//example of how array is setup in the way I want, this part works. 
foreach($results as $i => $a): 
$items[$a['id']] = [ // THIS CHANGED. 
    "id" => $a['id'], 
    "itemid" => $a['itemid'], 
    ... 

nun mit jedem weiteren Ergebnis, können Sie leicht prüfen, ob die ID bereits im Array ist:

if (isset($items[$a['id']])) { 
    // We had this id before, just add files/tags to it. 
    // Check first, if files subarray exists, if not: create it. 
    if (!isset($items[$a['id']]['files'])) { 
    $items[$a['id']]['files'] = array(); 
    } 
    $items[$a['id']]['files'][] = array(...); // add the new file. 
    // Repeat for tags. 
} 

Wenn das Ergebnis der Rückkehr könnte gleiche Datei mehr als einmal für eine ID, können Sie überprüfen, ob der Dateiname unter Verwendung einer Suchfunktion schon drin ist:

$filename = $a['filename']; 
if (!searchFilename($filename, $items[$a['id']]['files']) { 
    // Filename is not in there, yet. 
    // Add file info. 
} 

function searchFilename($id, $array) { 
    foreach ($array as $key => $val) { 
    if ($val['filename'] === $id) { 
     return true; 
    } 
    } 
    return false; 
} 

Gleiches gilt für Tags in ähnlicher Weise.

Am Ende, wenn Sie die IDs für den Index von $items nicht wollen, rufen Sie einfach:

$items = array_values($items); 
+0

Ich denke ich verstehe, wo ich jetzt falsch gelaufen bin - mit dem Index.Falls mehr als eine zusätzliche Datei/Tag vorhanden ist, wird der falsche Index im Array gesucht. Vielen Dank für Ihre Erklärung und Zeit! Ich bin mir ziemlich sicher, dass Ihre Lösung für mich funktionieren wird. Ich werde bestätigen/markieren Lösung, sobald ich es in meinem Code: P (PS Sollte ich diese Frage entfernen, oder lassen Sie es? Der Fehler war in meiner Logik = P Fühlen Sie sich frei, Meinungen als Kommentare zu verlassen.) – turnfire

+0

Genau, da '$ i' unabhängig von' $ a ['id'] 'inkrementiert wird' wurde vorher verarbeitet oder nicht. – Paul

+0

Ich habe ein paar Änderungen vorgenommen, aber Ihre Lösung war, was ich brauchte. Ich habe die Art und Weise, wie mein Array eingerichtet wird, komplett geändert, indem ich die Datei/Tag-IDs als ihren Index verwendet habe. Danke nochmal Paul, du rockst! – turnfire