В настоящее время я закодировал способ превратить многомерный массив в значения, разделенные запятыми (для упрощения отладки я использую каналы вместо запятых). Проблема в том, что я знаю, что код, который я использую для этого, ужасен. Он работает так, как я хочу, но это совсем не приятно.
Что мне нужно
В настоящее время arr_to_csv()
работает для пяти уровней вложенных данных в многомерном массиве. Мне нужна рекурсивная функция для выполнения того же для одного или неограниченного количества вложенных массивов или хорошего подталкивания в правильном направлении. Рекурсия – это не моя сильная сторона, но я знаю, что это путь вперед.
Ввод данных
Многозначный массив передается функции.
array 'name' => array 'singular' => null 'plural' => null 'fields' => array 'price' => array 'label' => string 'Preis' (length=5) 'company_id' => array 'label' => null 'placeholder' => null //...the array could go on...
Функция возвращает следующее …
Это именно то, что я хочу …
0 => string 'name||singular||null' (length=20) 1 => string 'name||plural||null' (length=18) 2 => string 'fields||price||label||Preis' (length=27) 3 => string 'fields||company_id||label||null' (length=31) 4 => string 'fields||company_id||placeholder||null' (length=37) 5 => string 'fields||name||label||null' (length=25) 6 => string 'fields||name||placeholder||null' (length=31)
Моя ужасная построенная функция
Я не гожусь с рекурсией, так вот мой ужасный список foreach
s. Как вы можете видеть из приведенного ниже кода, это ужасно (нет необходимости читать все это, оно просто копирует себя). Пожалуйста, помогите мне разобраться в моем ужасном коде!
function arr_to_csv($data,$csv = '||') { $array = array(); /* Epic amount of for each's. This could be done with recursion */ foreach($data as $key => &$value) { if (!is_array($value)) { $array[] = $key . $csv .(is_null($value)?'null':$value); } else { foreach ($value as $k => &$v) { if (!is_array($v)) { $array[] = $key . $csv . $k . $csv . (is_null($v) ? 'null' : $v); } else { foreach ($v as $kk => &$vv) { if (!is_array($vv)) { $array[] = $key . $csv . $k . $csv . $kk . $csv . (is_null($vv) ? 'null' : $vv); } else { foreach ($vv as $x => &$y) { if (!is_array($y)) { $array[] = $key . $csv . $k . $csv . $kk . $csv. $x . $csv . (is_null($y) ? 'null' : $y); } else { foreach ($y as $too => $long) { if(!is_array($long)) { $array[] = $key . $csv . $k . $csv . $kk . $csv. $x . $csv . $too . $csv. (is_null($long)?'null':$long); } else { foreach ($long as $omg => $why) { if(!is_array($why)) { $array[] = $key . $csv . $k . $csv . $kk . $csv. $x . $csv . $too . $csv . $omg . $csv . (is_null($why) ? 'null' : $why); } } } } } } } } } } } } return $array; }
Это какой-то псевдокод, но это начало:
$strings = []; $flattenArray = function($arr, $level) use (&$strings, &$flattenArray) { foreach($arr as $key=>$value){ $s = &$strings[$level]; if(!isset($s)) { $s = array(); } $s[] = $key; if(is_array($value)) { $flattenArray($value, $level); } else { $s[] = $value; } $level ++; } }; $flattenArray($myArray, 0); foreach($strings as &$arr) { $arr = implode("||", $arr); }
Небольшая демонстрация с вашим массивом : http://codepad.viper-7.com/CR2SPY <- Это не работает полностью, но это начало
Вот демонстрация, которая, я думаю, работает так, как вы хотите: http://codepad.viper-7.com/shN4pH
Код:
$strings = []; $flattenArray = function($arr, $level, $k = null) use (&$strings, &$flattenArray) { foreach($arr as $key=>$value){ if($k === null) { $s = &$strings[$key]; } else { $s = &$strings[$k]; } if(!isset($s)) { $s = array(); } $str = &$s[$level]; if(!isset($str)) { $str = array(); if($k !== null) { $str[] = $k; } } $str[] = $key; if(is_array($value)) { $flattenArray($value, $level, ($k === null) ? $key : $k); } else { $str[] = is_null($value) ? "null" : $value; } $level ++; } }; $flattenArray($myArray, 0); $all = []; foreach($strings as $k => $arr){ $new = array(); foreach($arr as $ky => $ar) { $all[] = implode("||", $ar); } } print_r($all);
Я не проверял его, поэтому, если он не работает, его следует исправить.
function readarray($from_array, $addr = array()) { global $output; foreach ($from_array as $key => $value) { if (is_Array($value) && count($value) > 0) { $addr[] = $key; readarray($value, $addr); } else { $output[] = implode('||', $addr) . $value; } } } $output = array(); foreach ($my_array as $key=>$value){ readarray($value); }
// улучшено для получения отдельных массивов корня исходного массива
Не уверен, что это вам поможет, но не проще ли сначала сгладить массив, а затем форматировать так, как вы хотите? Чтобы сгладить массив, попробуйте следующее:
$array = "YOUR ARRAY"; $FlatArray = array(); foreach(new RecursiveIteratorIterator(new RecursiveArrayIterator($array)) as $k=>$v) { $FlatArray[$k] = $v; }
Пробовал все утро, чтобы придумать рекурсивную функцию для этого. Это так близко, как я получил. Может быть, вы можете улучшить это.
$data = array('name' =>array('singular' => NULL,'plural' => NULL,'fields' =>array('price' =>array('label' =>'Preis','company_id' =>array('label' => NULL,'placeholder' => NULL))))); function arr_to_csv($data,$csv = '||') { $list = ""; foreach($data as $key => &$value) { $list .= $key . $csv .((!is_array($value))?(is_null($value)?'null':$value): arr_to_csv($value))."<br>"; } return $list; } print_r(arr_to_csv($data));
Возвращает:
name||singular||null plural||null fields||price||label||Preis company_id||label||null placeholder||null