1

我目前已经编写了一种将多维数组转换为逗号分隔值的方法(为了便于调试,我使用管道而不是逗号)。问题是,我知道我用来执行此操作的代码非常糟糕。它按我想要的方式工作,但它一点都不好。

我需要的

目前,该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)

我可怕的构造函数

我不擅长递归,所以这是我糟糕的foreachs 列表。正如您从下面的代码中看到的那样,这很糟糕(无需阅读整个内容,它只是复制自己)。请帮我整理一下我可怕的代码!

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;
}
4

3 回答 3

2

这是一些伪代码,但它是一个开始:

$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);
于 2013-01-03T15:29:29.017 回答
1

不确定这是否会对您有所帮助,但是首先展平阵列然后以您想要的方式格式化不是更容易吗?要展平阵列,请尝试以下操作:

$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
于 2013-01-02T21:13:55.010 回答
1

我没有检查它,所以如果它不起作用,应该更正它。

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); 
}

// 改进以获取初始数组根的单独数组

于 2013-01-02T17:02:23.053 回答