2016-04-11 3 views
1

Я понимаю, что существует ряд вопросов о многомерных массивах и циклах foreach, и я потратил часы на их чтение и попытался заставить мой собственный цикл работать без успеха. Если решение является дубликатом, я удалю свой вопрос (или ссылку на другую, если это будет предпочтительнее).Многомерный цикл массива с поиском массива

Теперь задача:

  • Используя массив возвращаемых результатов MYSQL. Результаты получены из нескольких объединенных таблиц в ассоциативном массиве. Теперь мне нужно преобразовать его в многомерный массив, в котором я нуждаюсь.
  • У меня есть большая часть его работы, но моя проблема зацикливается и добавляет новые элементы в нужное место в массиве.

Вот код:

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

Тогда я попробовал несколько способов перебрать, чтобы только добавить к «метки» или «файлы», если элемент «Идентификатор» является то же самое, что и последнее. Вот текущий код в моем редакторе, не работает:

//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 

Как вы можете видеть, моя последняя попытка была использовать in_array, что теперь я понимаю, не работает на многомерных массивов. Моя проблема в том, что я не могу понять, как определить, есть ли новый файл или новый тег для одного и того же элемента.

В конечном счете, я хочу массив «элементов», которые имеют несколько «файлов» и «тегов». Я буду json_encode и использовать его с JS потом.

Любые советы о том, как получить эту работу или оптимизировать ее, были бы весьма признательны.

P.S. Как я уже упоминал выше, я знаю, что этот вопрос задавали раньше - хотя я не смог заставить свои решения работать для меня. Я удалю этот вопрос, если решение является дубликатом (как, впрочем, это не очень полезно для других). Спасибо за любую помощь, мы очень благодарны!

+0

Что ваш PHP версии? На PHP> = 5.5 вы можете использовать ['array_column'] (http://php.net/manual/en/function.array-column.php):' in_array ($ a ['filename'], array_column ($ items [$ i-1] ['files'], 'name')) ' – fusion3k

+0

Спасибо за подсказку @ fusion3k. Я прочитаю документы об этой функции и попробую. – turnfire

ответ

0

Не используйте индексы массива «autoincrementing», так как они легко перепутаны. Используйте свой идентификатор базы данных, так как это уже есть:

//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'], 
    ... 

Теперь, когда какой-либо дополнительный результат, вы можете легко проверить, если идентификатор уже в массиве:

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. 
} 

Если ваш результат может вернуть тот же файл несколько раз для идентификатора, вы можете проверить, если файл уже существует, используя функцию поиска:

$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; 
} 

то же самое относится и к тегам аналогичным образом.

В конце концов, если вы не хотите, идентификаторы для индекса $items, просто позвоните:

$items = array_values($items); 
+0

Думаю, я понимаю, где я сейчас ошибся - используя индекс.В случае, если имеется более одного дополнительного файла/тега, он ищет неправильный индекс в массиве. Спасибо за ваше объяснение и время! Я уверен, что ваше решение будет работать на меня. Я подтвержу/отметьте решение, как только я получу его в своем коде: P (PS Следует ли удалить этот вопрос или оставить его? Недостаток был в моей логике = P Не стесняйтесь оставлять отзывы в комментариях.) – turnfire

+0

Точно, поскольку '$ i' увеличивается, независимо от' $ a ['id'] 'обрабатывался до или без. – Paul

+0

Я сделал несколько изменений, но ваше решение было тем, что мне было нужно. Я полностью изменил способ настройки моего массива, используя идентификаторы файлов/тегов в качестве индекса. Еще раз спасибо, Пол! – turnfire

Смежные вопросы