PHP array_merge_recursive带有数字键

时间:2021-08-13 10:45:06

So I'm suppose to build a multidimensional array dynamically from a text file, and everything works perfectly except that the numeric keys are screwing me over...

所以我假设从一个文本文件动态地构建一个多维数组,所有的东西都运行得很好,除了数字键把我搞糊涂了……

The text file looks something like this:

文本文件如下所示:

a=1
b.c=2
b.d.0.e=3
b.d.0.f=4
b.d.1.e=5
b.d.1.f=6

As the array_merge_recursive doesn't work with numeric keys, the output is like:

由于array_merge_recursive不支持数字键,因此输出如下:

array(2) { 
 ["a"]=>  
 string(3) "1" 
 ["b"]=>  
 array(2) { 
  ["c"]=>  
  string(3) "2" 
  ["d"]=>  
  array(4) { 
   [0]=>  
   array(1) { 
    ["e"]=>  
    string(9) "3" 
   } 
   [1]=>  
   array(1) { 
    ["f"]=>  
    string(4) "4" 
   } 
   [2]=>  array(1) { 
    ["e"]=>  
    string(8) "5" 
   } 
   [3]=>  
   array(1) { 
    ["f"]=>  
    string(9) "6" 
 }}}}

Is there any easy solution to make the output like...?

有什么简单的解决办法使输出像…?

array(2) { 
 ["a"]=>  
 string(3) "1" 
 ["b"]=>  
 array(2) {
  ["c"]=>  
  string(3) "2" 
  ["d"]=>  
  array(2) { 
   [0]=>  
   array(2) { 
    ["e"]=>  
    string(9) "3" 
    ["f"]=>  
    string(4) "4"  
   } 
   [1]=>  
   array(3) { 
    ["e"]=>  
    string(9) "5"
    ["f"]=>  
    string(4) "6"
}}}}

Thanks

谢谢

3 个解决方案

#1


3  

You could break each bit into its components and build up the array one step at a time.

您可以将每个位分解成它的组件,每次构建一个数组。

$path = "b.d.0.e";
$val = 3;
$output = array();

$parts = explode(".", $path);

// store a pointer to where we currently are in the array.
$curr =& $output;

// loop through up to the second last $part
for ($i = 0, $l = count($parts); $i < $l - 1; ++$i) {
    $part = $parts[$i];

    // convert numeric strings into integers
    if (is_numeric($part)) {
        $part = (int) $part;
    }

    // if we haven't visited here before, make an array
    if (!isset($curr[$part])) {
        $curr[$part] = array();
    }

    // jump to the next step
    $curr =& $curr[$part];
}

// finally set the value
$curr[$parts[$l - 1]] = $val;

My output, using the same input as yours:

我的输出,使用与您相同的输入:

Array (
    [a] => 1
    [b] => Array (
        [c] => 2
        [d] => Array (
            [0] => Array (
                [e] => 3
                [f] => 4
            )
            [1] => Array (
                [g] => 5
                [h] => 6
            )
        )
    )
)

#2


0  

Or you could use eval():

或者可以使用eval():

$raw_data = file($txt_file, FILE_IGNORE_NEW_LINES);
foreach ($raw_data as $line) {
    list($keys, $value) = explode('=', $line);
    $keys = explode('.', $keys);
    $arr_str = '$result';
    foreach ($keys as $key) {
        if (ctype_digit($key)) {
            $arr_str .= "[" . $key . "]";
        } else {
            $arr_str .= "['" . $key . "']";
        }
    }
    eval($arr_str . ' = $value;');
}

print_r($result);

#3


0  

I know this is an old one, but the best solution I have found is to use array_replace_recursive. It will achieve what you are looking to do:

我知道这是一个老问题,但是我找到的最好的解决方案是使用array_replace_recursive.com。它将实现你所期望的:

$start = array(
   "600" => array("total" => 100),
   "700" => array("total" => 200)
);

$finish = array(
  "600" => array("average" => 25),
  "700" => array("average" => 50)
);

$out = array_replace_recursive($start,$finish);
var_dump($out):

array(2) {
  [600]=>
  array(2) {
    ["total"]=>
    int(100)
    ["average"]=>
    int(25)
  }
  [700]=>
  array(2) {
    ["total"]=>
    int(200)
    ["average"]=>
    int(50)
  }
}

#1


3  

You could break each bit into its components and build up the array one step at a time.

您可以将每个位分解成它的组件,每次构建一个数组。

$path = "b.d.0.e";
$val = 3;
$output = array();

$parts = explode(".", $path);

// store a pointer to where we currently are in the array.
$curr =& $output;

// loop through up to the second last $part
for ($i = 0, $l = count($parts); $i < $l - 1; ++$i) {
    $part = $parts[$i];

    // convert numeric strings into integers
    if (is_numeric($part)) {
        $part = (int) $part;
    }

    // if we haven't visited here before, make an array
    if (!isset($curr[$part])) {
        $curr[$part] = array();
    }

    // jump to the next step
    $curr =& $curr[$part];
}

// finally set the value
$curr[$parts[$l - 1]] = $val;

My output, using the same input as yours:

我的输出,使用与您相同的输入:

Array (
    [a] => 1
    [b] => Array (
        [c] => 2
        [d] => Array (
            [0] => Array (
                [e] => 3
                [f] => 4
            )
            [1] => Array (
                [g] => 5
                [h] => 6
            )
        )
    )
)

#2


0  

Or you could use eval():

或者可以使用eval():

$raw_data = file($txt_file, FILE_IGNORE_NEW_LINES);
foreach ($raw_data as $line) {
    list($keys, $value) = explode('=', $line);
    $keys = explode('.', $keys);
    $arr_str = '$result';
    foreach ($keys as $key) {
        if (ctype_digit($key)) {
            $arr_str .= "[" . $key . "]";
        } else {
            $arr_str .= "['" . $key . "']";
        }
    }
    eval($arr_str . ' = $value;');
}

print_r($result);

#3


0  

I know this is an old one, but the best solution I have found is to use array_replace_recursive. It will achieve what you are looking to do:

我知道这是一个老问题,但是我找到的最好的解决方案是使用array_replace_recursive.com。它将实现你所期望的:

$start = array(
   "600" => array("total" => 100),
   "700" => array("total" => 200)
);

$finish = array(
  "600" => array("average" => 25),
  "700" => array("average" => 50)
);

$out = array_replace_recursive($start,$finish);
var_dump($out):

array(2) {
  [600]=>
  array(2) {
    ["total"]=>
    int(100)
    ["average"]=>
    int(25)
  }
  [700]=>
  array(2) {
    ["total"]=>
    int(200)
    ["average"]=>
    int(50)
  }
}