У меня такой многомерный массив:
array(2) { [1]=> array(3) { ["eventID"]=> string(1) "1" ["eventTitle"]=> string(7) "EVENT 1" ["artists"]=> array(3) { [4]=> array(2) { ["name"]=> string(8) "ARTIST 1" ["description"]=> string(13) "artist 1 desc" ["links"]=> array(2) { [1]=> array(2) { ["URL"]=> string(22) "http://www.artist1.com" } [6]=> array(2) { ["URL"]=> string(24) "http://www.artist1-2.com" } } } [5]=> array(2) { ["name"]=> string(8) "ARTIST 8" ["description"]=> string(13) "artist 8 desc" ["links"]=> array(1) { [8]=> array(2) { ["URL"]=> string(22) "http://www.artist8.com" } } } [2]=> array(2) { ["ime"]=> string(8) "ARTIST 5" ["opis"]=> string(13) "artist 5 desc" ["links"]=> array(1) { [9]=> array(2) { ["URL"]=> string(22) "http://www.artist5.com" } } } } } [2]=> array(3) { ["eventID"]=> string(1) "2" ["eventTitle"]=> string(7) "EVENT 2" ["artists"]=> array(3) { [76]=> array(2) { ["name"]=> string(9) "ARTIST 76" ["description"]=> string(14) "artist 76 desc" ["links"]=> array(1) { [13]=> array(2) { ["URL"]=> string(23) "http://www.artist76.com" } } } [4]=> array(2) { ["name"]=> string(8) "ARTIST 4" ["description"]=> string(13) "artist 4 desc" ["links"]=> array(1) { [11]=> array(2) { ["URL"]=> string(22) "http://www.artist4.com" } } } } } }
Я хотел бы сделать вывод html следующим образом:
–
СОБЫТИЕ 1
ХУДОЖНИК 1
художник 1 по убыванию
http://www.artist1.com , http://www.artist1-2.com
ХУДОЖНИК 8
исполнитель 8 desc
http://www.artist8.com
ХУДОЖНИК 5
исполнитель 5 desc
http://www.artist5.com
–
СОБЫТИЕ 2
ХУДОЖНИК 76
художник 76 по убыванию
http://www.artist76.com
ХУДОЖНИК 4
художник 4 по убыванию
http://www.artist4.com
–
и т.п.
Я запутался в том, чтобы копать все глубже и глубже в массивах, особенно когда мои ключи массива не являются последовательными номерами, а идентификаторами исполнителя / ссылки / и т. Д.
Честно говоря, эти массивы убьют меня! знак равно
Спасибо за любую помощь заранее!!!
Лучше всего использовать конструкцию foreach
создания петли над вашим массивом. Следующее непроверено и с моей головы (и, вероятно, поэтому не так продумано, как должно быть!), Но должно дать вам хорошее начало:
foreach ($mainArray as $event) { print $event["eventTitle"]; foreach ($event["artists"] as $artist) { print $artist["name"]; print $artist["description"]; $links = array(); foreach ($artist["links"] as $link) { $links[] = $link["URL"]; } print implode(",", $links); } }
Заявление foreach
позаботится обо всем этом для вас, включая ассоциативные хеши. Как это:
foreach($array as $value) { foreach($value as $key => $val) { if($key == "links") { } /* etc */ } }
Я думаю, что хороший способ приблизиться к этому – «снизу вверх», т.е. определить, что делать с внутренними значениями, затем использовать эти результаты для разработки следующего уровня и так далее, пока мы не достигнем вершины. Также неплохо написать наш код в небольших, одноцелевых, повторно используемых функциях, насколько это возможно, так что я буду делать.
Обратите внимание, что я буду считать ваши данные безопасными (т. Е. Он не был предоставлен потенциально злонамеренным пользователем). Я также предполагаю, что ключи «ime» и «opi» предназначены для соответствия «имени» и «описанию» других массивов;)
Мы можем игнорировать самые внутренние строки, так как нам не нужно их модифицировать. В этом случае внутренняя структура, которую я вижу, – это отдельные ссылки, которые представляют собой массивы, содержащие значение «URL». Вот код для рендеринга одной ссылки:
function render_link($link) { return "<a href='{$link['URL']}'>{$link['URL']}</a>"; }
Это уменьшило массив до строки, поэтому мы можем использовать его для удаления самого внутреннего слоя. Например:
// Input array('URL' => "http://www.artist1.com") // Output "<a href='http://www.artist1.com'>http://www.artist1.com</a>"
Теперь мы перемещаем слой в массивы 'links'. Здесь нужно сделать две вещи: применить «render_link» к каждому элементу, что мы можем сделать с помощью «array_map», а затем уменьшить результирующий массив строк до одной разделенной запятой строки, которую мы можем сделать с помощью «implode», функция:
function render_links($links_array) { $rendered_links = array_map('render_link', $links_array); return implode(', ', $rendered_links); }
Это удалило другой слой, например:
// Input array(1 => array('URL' => "http://www.artist1.com"), 6 => array('URL' => "http://www.artist1-2.com")) // Output "<a href='http://www.artist1.com'>http://www.artist1.com</a>, <a href='http://www.artist1-2.com'>http://www.artist1-2.com</a>"
Теперь мы можем выйти на другой уровень для отдельного художника, который представляет собой массив, содержащий «имя», «описание» и «ссылки». Мы знаем, как визуализировать «ссылки», поэтому мы можем уменьшить их до одной строки, разделенной линиями:
function render_artist($artist) { // Replace the artist's links with a rendered version $artist['links'] = render_links($artist['links']); // Render this artist's details on separate lines return implode("\n<br />\n", $artist); }
Это удалило другой слой, например:
// Input array('name' => 'ARTIST 1', 'description' => 'artist 1 desc', 'links' => array( 1 => array( 'URL' => 'http://www.artist1.com') 6 => array( 'URL' => 'http://www.artist1-2.com'))) // Output "ARTIST 1 <br /> artist 1 desc <br /> <a href='http://www.artist1.com'>http://www.artist1.com</a>, <a href='http://www.artist1-2.com'>http://www.artist1-2.com</a>"
Теперь мы можем переместить слой в «массивы художников». Так же, как если бы мы перешли от одной ссылки к массивам 'links', мы сможем использовать array_map для обработки содержимого и implode, чтобы объединить их:
function render_artists($artists) { $rendered = array_map('render_artist', $artists); return implode("\n<br /><br />\n", $rendered); }
Это удалило другой слой (нет примера, потому что он слишком длинный;))
Затем у нас есть событие, которое мы можем решить так же, как и для художника, хотя я также удалю идентификационный номер и отформатирую название:
function render_event($event) { unset($event['eventID']); $event['eventTitle'] = "<strong>{$event['eventTitle']}</strong>"; $event['artists'] = render_artists($event['artists']); return implode("\n<br />\n", $event); }
сfunction render_event($event) { unset($event['eventID']); $event['eventTitle'] = "<strong>{$event['eventTitle']}</strong>"; $event['artists'] = render_artists($event['artists']); return implode("\n<br />\n", $event); }
Теперь мы достигли внешнего массива, который представляет собой массив событий. Мы можем справиться с этим так же, как и для массивов художников:
function render_events($events) { $rendered = array_map('render_event', $events); return implode("\n<br /><br />--<br /><br />", $rendered); }
Вы можете остановиться здесь, так как передача вашего массива в render_events даст вам обратно HTML-код, который вы хотите:
echo render_events($my_data);
Однако, если мы хотим больше попробовать, мы можем попытаться реорганизовать только что написанный код, чтобы быть менее избыточным и более пригодным для повторного использования. Один простой шаг – избавиться от render_links, render_artists и render_events, поскольку все они являются вариантами более общего шаблона:
function reduce_with($renderer, $separator, $array) { return implode($separator, array_map($renderer, $array)); } function render_artist($artist) { $artist['links'] = reduce_with('render_link', ', ', $artist['links']); return implode("\n<br />\n", $artist); } function render_event($event) { unset($event['eventID']); $event['eventTitle'] = "<strong>{$event['eventTitle']}</strong>"; $event['artists'] = reduce_with('render_artist', "\n<br /><br />\n", $event['artists']); return implode("\n<br />\n", $event); } echo reduce_with('render_event', "\n<br /><br />--<br /><br />", $my_data);
сfunction reduce_with($renderer, $separator, $array) { return implode($separator, array_map($renderer, $array)); } function render_artist($artist) { $artist['links'] = reduce_with('render_link', ', ', $artist['links']); return implode("\n<br />\n", $artist); } function render_event($event) { unset($event['eventID']); $event['eventTitle'] = "<strong>{$event['eventTitle']}</strong>"; $event['artists'] = reduce_with('render_artist', "\n<br /><br />\n", $event['artists']); return implode("\n<br />\n", $event); } echo reduce_with('render_event', "\n<br /><br />--<br /><br />", $my_data);
Если это часть более крупного приложения, мы можем захотеть выделить еще несколько общих шаблонов. Это делает код немного более сложным, но гораздо более пригодным для повторного использования. Вот несколько шаблонов, которые я заметил:
// Re-usable library code // Partial application: apply some arguments now, the rest later function papply() { $args1 = func_get_args(); return function() use ($args1) { return call_user_func_array( 'call_user_func', array_merge($args1, func_get_args())); }; } // Function composition: chain functions together like a(b(c(...))) function compose() { $funcs = array_reverse(func_get_args()); $first = array_shift($funcs); return function() use ($funcs, $first) { return array_reduce($funcs, function($x, $f) { return $f($x); }, call_user_func_array($first, func_get_args())); }; } // Transform or remove a particular element in an array function change_elem($key, $func, $array) { if is_null($func) unset($array[$key]); else $array[$key] = $func($array[$key]); return $array; } // Transform all elements then implode together function reduce_with($renderer, $separator) { return compose(papply('implode', $separator), papply('array_map', $renderer)); } // Wrap in HTML function tag($tag, $text) { return "<{$tag}>{$text}</{$tag}>"; } // Problem-specific code function render_link($link) { return "<a href='{$link['URL']}'>{$link['URL']}</a>"; } $render_artist = compose( papply('implode', "\n<br />\n"), papply('change_elem', 'links', papply('reduce_with', 'render_link', ', ')); $render_event = compose( papply('implode', "\n<br />\n"), papply('change_elem', null, 'eventID'), papply('change_elem', 'eventTitle', papply('tag', 'strong')), papply('change_elem', 'artists', papply('reduce_with', $render_artist, "\n<br /><br />\n"))); echo reduce_with($render_event, "\n<br /><br />--<br /><br />", $my_data);