1

現在、多次元配列をコンマ区切りの値に変換する方法をコーディングしています (デバッグを容易にするために、コンマの代わりにパイプを使用しています)。問題は、これを行うために使用するコードがひどいものであることを知っていることです。それは私が望むように機能しますが、まったく良くありません。

必要なもの

現在、このarr_to_csv()関数は、多次元配列内の 5 レベルのネストされたデータに対して機能します。1つまたは無制限のネストされた配列に対して同じことを実行する再帰関数、または正しい方向への適切な微調整が必​​要です。再帰は私の長所ではありませんが、それが前進する方法であることは知っています。

データ入力

多次元配列が関数に渡されます。

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 に答える