أفضل طريقة لدمج المصفوفة بشكل متكرر دون كتابة مفاتيح تكرار

StackOverflow https://stackoverflow.com/questions/3739179

سؤال

لدي مجموعة متعددة الأبعاد من بيانات النموذج التي لم يتم تحديدها من 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'
);

لن أعرف أبدًا على وجه اليقين مدى عمق المصفوفة/التجزئة - يكون ذلك مستويين فقط كما هو موضح هنا أو يمكن أن يكون 5.

هذا أيضًا في Symfony 1.4 ، لذا فإن SFFORM مع جميع الكماليات المتوفرة إذا لزم الأمر. أعتقد أنه يجب أن تكون هناك طريقة معقولة للقيام بذلك باستخدام مخطط (مخطط) عنصر واجهة المستخدم. ومع ذلك ، أود تجنب ربط البيانات مرة أخرى إلى النموذج إن أمكن. هذا ليس جزءًا من عملية تقديم النموذج الفعلية ، ولكنها منفصلة تمامًا في إجراء للمسؤولين لتنزيل مجموعات البيانات المقدمة.

هل كانت مفيدة؟

المحلول

مجرد صخب سريع ولكنه يعمل بشكل جيد:

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"
}

*/

نصائح أخرى

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

وماذا عن هذا؟ لم أكن أعرف كيف تريد التعامل مع المفاتيح المكررة ، لذلك تركت هذا الخيار متروك لك. فقط استبدل ; // 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);
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top