简体   繁体   English

以数学方式添加两个多维数组的最有效方法?

[英]Most efficient way to mathematically add two multidimensional arrays?

Consider two simple arrays: 考虑两个简单的数组:

<?php
  $array1 = array(
    'blue' => 5,

    'green' => array(
      'square' => 10,
      'sphere' => 0.5,
      'triangle' => 3
    ),

    'red' => array(
      'circle' => 1000,
    ),

    'black' => 4,

  );

  $array2 = array(
    'blue' => 1,

    'green' => array(
       'square' => 11,
       'circle' => 5,
    ),

    'purple' => 10,

    'yellow' => array(
      'triangle' => 4
    ),

    'black' => array(
      'circle' => 6,
    ),

  );

I need to mathmatically add together in a recursive way, each value from each $array1 and $array2 . 我需要以递归方式以数学方式将每个$array1$array2每个值相加。

  • Preserve keys 保留钥匙
  • Where a key does not exist in $array1 but does exist in $array2 , the final array would simply contain the value of $array2 (and the other way around as well) 如果$array1中不存在键但$array2中存在键,则最终数组将只包含$array2的值( $array2
  • Where they exist in both, the numeric values would be added + 如果两者都存在,则数值将加上+
  • Non-numeric values wouldn't be touched 不会触及非数字值
  • If a value on $array1 points to another sub-array, and in $array2 it points to a value, the end value would result in that key containing a subarray that contains the values from $array1 plus a new key/value using the parent name and it's value (see black in the example) 如果$array1上的值指向另一个子数组,并且$array2中的值指向一个值,则结束值将导致该键包含一个子数组,该子数组包含$array1中的值加上使用父项的新键/值名称及其值(请参阅示例中的black
  • Should be able to work at virtually unlimited nesting 应该能够在几乎无限制的嵌套中工作

To clarify, eg if we said 澄清,例如,如果我们说

<?php 
  $final = array_merge_special($array1, $array2);

  // We would end up with, if you var_export()'d final, something like:
  // (Note: Hope I didn't make mistakes in this or it will be confusing,
  // so expect mild human error)

  $final = array(
    'blue' => 6, // 5+1

    'green' => array(
      'square' => 21, // (10+11)
      'sphere' => 0.5, // only in $array1
      'triangle' => 3 // only in $array1
      'circle' => 5, // only in $array2
    ),

    'purple' => 10, // only in $array2

    'yellow' => array( // only in $array2
      'triangle' => 4
    ),

    'red' => array( // only in $array1
      'circle' => 1000,
    ),

    'black' => array(
      'circle' => 6, // untouched, while $black is present in both, the $array1 value does not have a 'circle' key, and is actually only a key/value (see below)
      'black' => 4, // the key/value from $array1 that was not a subarray, even though it was a subarray in $array2
    ),

  );

This seems outragously daunting to me. 这对我来说似乎非常令人生畏。 I know I could loop over one array and get easily recursively add the values, and I have this working (somewhat), but it's when I get into special rules (such as ones for black ) that I can't even imagine how broken code would look. 我知道我可以循环遍历一个数组,并轻松递归添加值,我有这个工作(有点),但它是当我进入特殊规则(如black ),我甚至无法想象如何破坏代码看起来。 There has to be a way to do this would looping over each array individually and unset() 'ing values to merge? 必须有一种方法可以单独循环遍历每个数组并unset()要合并的值吗?

You would use array_walk_recursive (see: See php Manual here ) and possibly array_merge_recursive. 您将使用array_walk_recursive(请参阅: 请参阅此处的php手册 )以及可能的array_merge_recursive。 I'd have to think it through further to get the full picture. 我必须进一步思考才能全面了解情况。

OK, decided that this wouldn't work! 好的,决定这不行! Array_walk_recursive doesn't pass keys that hold arrays to the function. Array_walk_recursive不会将包含数组的键传递给函数。 This problem kept flowing aroung in my brain, so I just had to write a function to do it! 这个问题一直在我的大脑中流动,所以我只需要编写一个功能来完成它! Here it is: 这里是:

function dosum($arin) {
  $arout = array();
  foreach ($arin as $key1 => $item1) {
    $total = 0;
    if(is_array($item1)) {
      foreach($item1 as $key2 => $item2) {
        if(is_numeric($key2))
          $total += $item2;
        else
          if(is_array($item2))
            $arout[$key1] = dosum(array($key2 => $item2));
          else
            $arout[$key1][$key2] =$item2;
      }
      if($total)
        if(isset($arout[$key1]))
          $arout[$key1][$key1] = $total;
        else
          $arout[$key1] = $total;
      }
    else
      $arout[$key1] = $item1;    
    }
  return $arout;
  }

For the 2 arrays given, you would use it like this: 对于给定的2个数组,您可以像这样使用它:

print_r(dosum(array_merge_recursive($array1, $array2)));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM