我认为一ç§�好的方法是“自下而上â€�,å�³å…ˆå¤„ç�†æœ€å†…部的值,然å��使用这些结æ�œæ�¥å¤„ç�†ä¸‹ä¸€ä¸ªçº§åˆ«ï¼Œä¾�æ¤ç±»æ�¨ï¼Œç›´åˆ°è¾¾åˆ°é¡¶éƒ¨ã€‚在å�¯èƒ½çš„情况下,尽å�¯èƒ½åœ°ç¼–写我们的代ç �,使其æˆ�为å°�å�‹ã€�å�•ä¸€ç”¨é€”ã€�å�¯é‡�å¤�使用的函数,这也是一个好的å®�践。
请注�,我将�设您的数�是安全的(�它没有由潜在的��用户�供)。我还将�设键“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) {
$artist['links'] = render_links($artist['links']);
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>"
现在我们可以将一个层级移出到“artists”数组中。就像我们从单个链接转移到“links”数组时一样,我们可以使用array_map处理内容并使用implode将它们连接在一起:
function render_artists($artists) {
$rendered = array_map('render_artist', $artists);
return implode("\n<br /><br />\n", $rendered);
}
这个已经移除了另一个层级(没有示例,因为它变得太长了 ;))
接下来我们有一个事件,我们可以用同样的方式解决艺术家问题,尽管我也会删除ID号码并格式化标题:
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 papply() {
$args1 = func_get_args();
return function() use ($args1) {
return call_user_func_array(
'call_user_func',
array_merge($args1, func_get_args()));
};
}
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()));
};
}
function change_elem($key, $func, $array) {
if is_null($func) unset($array[$key]);
else $array[$key] = $func($array[$key]);
return $array;
}
function reduce_with($renderer, $separator) {
return compose(papply('implode', $separator),
papply('array_map', $renderer));
}
function tag($tag, $text) {
return "<{$tag}>{$text}</{$tag}>";
}
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);