PHP nasıl çok boyutlu bir dizi ters yok

2 Cevap php

Nedir çok boyutlu bir dizi ters çevirmek için en kolay yolu. Invert derken array_flip benzer anlamına gelir.

ör

[0][5][var_name] = data
[0][3][var_name2] = data2
[1][var_name3] = data3
[0][1][4][var_name4] = data4

ters olacaktır:

[var_name][0][5] = data
[var_name2][0][3] = data2
[var_name3][1] = data3
[var_name4][0][1][4] = data4

Herhangi bir fikir?

2 Cevap

Tüm atalarının tuşlarının bir listesini saklamak ve "saygısız" sürümünü oluşturmak için bu listeyi kullanabilirsiniz bir "yaprak" vurduğunuzda. Olabilir

<?php
$data = array(
  0=>array(
    5=>array('var_name' => 'data'),
    3=>array('var_name2' => 'data2'),
    1=>array(4=>array('var_name4'=>'data4'))
  ),
  1=>array('var_name3'=>'data3')
);

$result = array();
foo($data, $result);

($result['var_name'][0][5] === 'data') or die('1');
($result['var_name2'][0][3] === 'data2') or die('2');
($result['var_name3'][1] === 'data3') or die('3');
($result['var_name4'][0][1][4] === 'data4') or die('4');
echo 'ok';


function foo(array $a, array &$target, $stack=array()) {
  foreach($a as $key=>$value) {
    if ( is_array($value) ) {
      array_push($stack, $key);
      foo($value, $target, $stack);
      array_pop($stack);
    }
    else {
      $target[$key] = array();
      $tmp = &$target[$key];
      foreach( $stack as $s ) { // now it's not so stack-ish anymore :-S
        $tmp[$s] = array();
        $tmp = &$tmp[$s];
      }
      $tmp = $value;
    }
  }
}

Bunu yapmak için kolay bir yol gelmiyordu. Yani bunu yapmak için gerçekten çok karmaşık bir şekilde yazdı. Yani:

  1. Çok boyutlu dizi çekmek ve anahtarları ve değerleri bir liste halinde dümdüz.
  2. Tuşları ters.
  3. Ters bir boyutlu dizi elde etmek için listeyi Unflatten.

Code

<?php
function print_entries($array, $prekeys = array())
{
    foreach ($array as $key => $value)
    {
        $keys = array_merge($prekeys, array($key));

        if (is_array($value))
            print_entries($value, $keys);
        else
            echo '[' . implode('][', $keys) . "] = $value\n";
    }
}

function flatten_array($array)
{
    $entries = array();

    foreach ($array as $key => $value)
    {
        if (is_array($value))
        {
            foreach (flatten_array($value) as $subentry)
            {
                $subkeys  = $subentry[0];
                $subvalue = $subentry[1];

                $entries[] = array(array_merge(array($key), $subkeys), $subvalue);
            }
        }
        else
            $entries[] = array(array($key), $value);
    }

    return $entries;
}

function unflatten_array($entries)
{
    $array = array();

    foreach ($entries as $entry)
    {
        $keys  = $entry[0];
        $value = $entry[1];

        $subarray = &$array;

        foreach ($keys as $i => $key)
        {
            if ($i < count($keys) - 1)
            {
                if (!isset($subarray[$key]))
                    $subarray[$key] = array();

                $subarray = &$subarray[$key];
            }
            else
                $subarray[$key] = $value;
        }
    }

    return $array;
}

function invert_array($array)
{
    $entries = flatten_array($array);

    foreach ($entries as &$entry)
        $entry[0] = array_reverse($entry[0]);

    return unflatten_array($entries);
}

$array = array
(
    0 => array
    (
        5 => array('var_name' => 'data'),
        3 => array('var_name2' => 'data2'),
        1 => array(4 => array('var_name4' => 'data4'))
    ),

    1 => array(0 => array('var_name' => 'data3'))
);

print_entries($array);
echo "\n";
print_entries(invert_array($array));
?>

Output

[0][5][var_name] = data
[0][3][var_name2] = data2
[0][1][4][var_name4] = data4
[1][0][var_name] = data3

[var_name][5][0] = data
[var_name2][3][0] = data2
[var_name4][4][1][0] = data4
[var_name][0][1] = data3

Edit: Sana anahtarları ters yok ama sadece ön ucundan var_name kısmını taşımak ve yalnız sayısal endeksleri bırakın şimdi fark ettim. Ben yeniden sipariş farklı bir şekilde tuşlar için array_reverse çağırır burada flatten_array içinde hattını değiştirmek için yeterince kolay. Çekirdek düzleştirmek / unflatten mantığı değiştirilmesine gerek olmazdı. Ben okuyucu için bir alıştırma olarak bırakıyoruz. :-)