2009-10-11 3 views
3

У меня есть многомерный массив так:Looping многомерного массива в PHP

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 вывода, как это:

-

EVENT 1
ARTIST 1
artist 1 desc
http://www.artist1.com, http://www.artist1-2.com

ХУДОЖНИК 8
художника 8 убывание
http://www.artist8.com

ХУДОЖНИК 5
исполнитель 5 убывание
http://www.artist5.com

-

EVENT 2
ХУДОЖНИК 76
художник 76 убывание
http://www.artist76.com

ХУДОЖНИК художник 4 убывание
http://www.artist4.com

-

т.д.

Я запутался о копать глубже и глубже в массивах , особенно когда мои ключи массива не являются последовательными номерами, а идентификаторами исполнителя/ссылки/и т. д.
Эти массивы убьют меня, честно! =)

Благодарим за любую помощь заранее!

ответ

11

Вы лучше с помощью 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); 
    } 
} 
+0

Спасибо вам за помощь !!! Этот пример выглядит лучше для меня, поэтому я выбираю это для ответа, но я также вознагражу другой ответ, потому что считаю его полезным так же, как этот =) – errata

6

В заявлении foreach вы позаботитесь обо всем этом, включая ассоциативные хэши. Как это:

foreach($array as $value) { 
    foreach($value as $key => $val) { 
     if($key == "links") { 

     } 
     /* etc */ 
    } 
} 
5

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

Обратите внимание, что я буду считать ваши данные безопасными (то есть, они не были предоставлены потенциально злонамеренным пользователем).Я также предполагаю, что ключи «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); 
Смежные вопросы