【问题标题】:PHP array_merge_recursive with numeric keys带有数字键的 PHP array_merge_recursive
【发布时间】:2011-01-04 04:36:06
【问题描述】:

所以我想从一个文本文件动态构建一个多维数组,除了数字键让我搞砸之外,一切都完美无缺......

文本文件如下所示:

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

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

是否有任何简单的解决方案可以使输出类似于...?

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

谢谢

【问题讨论】:

  • 答案中的任何解决方案都可以工作,但我建议任何存储这样数据的人更合适地完成(例如,使用 json 字符串)。

标签: php arrays merge key numeric


【解决方案1】:

我知道这是一个旧的,但我发现最好的解决方案是使用 array_replace_recursive。它将实现您想要做的事情:

$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)
  }
}

【讨论】:

    【解决方案2】:

    或者你可以使用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】:

      您可以将每个位分解为其组成部分,然后一步一步构建数组。

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

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

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

      【讨论】:

      • 感谢您的好回答 :) 虽然不需要 if(is_numeric),但我认为它已经将 var 解释为 int。
      猜你喜欢
      • 2012-08-16
      • 1970-01-01
      • 2015-02-01
      • 1970-01-01
      • 2011-01-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-07
      相关资源
      最近更新 更多