Я думаю, это хороший способ решения этой проблемы является «снизу вверх», т.е. определить, что делать с внутренними значениями, затем использовать эти результаты для разработки следующего уровня и так далее, пока мы не достигнем вершины. Также неплохо написать наш код в небольших, одноцелевых, повторно используемых функциях, насколько это возможно, так что я буду делать.
Обратите внимание, что я буду считать ваши данные безопасными (то есть, они не были предоставлены потенциально злонамеренным пользователем).Я также предполагаю, что ключи «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>"
Теперь мы можем двигаться из слоя в массивы 'художников'. Так же, как когда мы перешли от одной ссылки на массивах "ссылки, мы можем использовать array_map для обработки содержимого и взрываться, чтобы присоединиться к ним вместе:
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_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);
Если это является частью более широкого применения, мы хотим, чтобы дразнить некоторые более общие закономерности. Это делает код немного более сложным, но гораздо более пригодным для повторного использования.Вот несколько узоров, которые я заметил:
// 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);
Спасибо вам за помощь !!! Этот пример выглядит лучше для меня, поэтому я выбираю это для ответа, но я также вознагражу другой ответ, потому что считаю его полезным так же, как этот =) – errata