2

我有一个从 YAML 反序列化的表单数据的多维数组。因此,它看起来像这样:

Array(
  'name' => 'Somone',
  'email' => 'someone@none.local',
  'billing' => Array(
     'address_1' => '1234 Somewhere'
     'address_2' => NULL,
     'city' => 'Somewhere',
     'state' => 'ST'
     'country' => 'CO'
     'postal_code' => '12345'
   ),
  'shipping' => Array(
     'address_1' => '1234 Somewhere'
     'address_2' => NULL,
     'city' => 'Somewhere',
     'state' => 'ST'
     'country' => 'CO'
     'postal_code' => '12345'
  )
);

我需要做的是把它展平,这样我就可以输出一些 CSV,所以它应该看起来像这样:

Array(
  'name' => 'Somone',
  'email' => 'someone@none.local',
  'billing_address_1' => '1234 Somewhere'
  'billing_address_2' => NULL,
  'billing_city' => 'Somewhere',
  'billing_state' => 'ST'
  'billing_country' => 'CO'
  'billing_postal_code' => '12345'
  'shipping_address_1' => '1234 Somewhere'
  'shipping_address_2' => NULL,
  'shipping_city' => 'Somewhere',
  'shipping_state' => 'ST'
  'shipping_country' => 'CO'
  'shipping_postal_code' => '12345'
);

我永远无法确定数组/散列有多深——它可能只有 2 个级别,如此处所示,也可能是 5 个级别。

这也在 Symfony 1.4 中,因此如果需要,可以使用 sfForm 及其所有的奢侈品。我认为应该有一种明智的方法来使用小部件架构和小部件来做到这一点。但是,如果可能的话,我想避免将数据绑定回表单。这不是实际表单提交过程的一部分,但在管理员下载提交数据集的操作中是完全独立的。

4

3 回答 3

2

只是一个快速破解,但效果很好:

function array_flatten($array, $prefix = '') {
    $newArray = array();
    foreach($array as $key => $value) {
        if(is_array($value)) {
                $newArray = array_merge($newArray, array_flatten($value, $key));
        }
        else {
                $index = empty($prefix) ? $key : $prefix.'_'.$key;
                $newArray[$index] = $value;
             }
     }
     return $newArray;
}

测试:

$a = array(
        "a" => "b",
        "ca" => array(
            "de" => "ef",
            "ef" => "gd"
        )
);

var_dump(array_flatten($a));

// Output:
/*

array(3) {
  ["a"]=>
  string(1) "b"
  ["ca_de"]=>
  string(2) "ef"
  ["ca_ef"]=>
  string(2) "gd"
}

*/
于 2010-09-17T21:40:33.017 回答
2
function flatten(Array $array, $name = '') {
    $ret = array();

    foreach ($array as $key => $value) {
        $itemname = ($name ? $name . '_' : '') . $key;

        if (is_array($value)) {
            $ret = array_merge($ret, flatten($value, $itemname));
        } else {
            $ret[$itemname] = $value;
        }
    }

    return $ret;
}
于 2010-09-17T21:42:52.943 回答
1

这个怎么样?我不知道你想如何处理重复的键,所以我把这个选项留给你。只需替换; // Do something here on duplicate key为您自己的代码即可。

$info = Array(
    'name' => 'Someone',
    'email' => 'someone@none.local',
    'billing' => Array(
        'address_1' => '1234 Somewhere',
        'address_2' => NULL,
        'city' => 'Somewhere',
        'state' => 'ST',
        'country' => 'CO',
        'postal_code' => '12345'
    ),
    'shipping' => Array(
        'address_1' => '1234 Somewhere',
        'address_2' => NULL,
        'city' => 'Somewhere',
        'state' => 'ST',
        'country' => 'CO',
        'postal_code' => '12345'
    )
);

function explodeArray($array, &$data, $prefix = "") {
    foreach ($array as $key => $value) {
        if (is_array($value)) {
            explodeArray($value, $data, $prefix . $key . "_");
        } else {
            if (!array_key_exists($prefix . $key, $data)) {
                $data[$prefix . $key] = $value;
            } else {
                ; // Do something here on duplicate key
            }
        }
    }
}

$result = array();
explodeArray($info, $result);

print_r($result);
于 2010-09-17T21:41:25.370 回答