【问题标题】:PHP: Average of multi-dimensional arrayPHP:多维数组的平均值
【发布时间】:2011-03-05 21:05:59
【问题描述】:

我正在尝试构建一个工具来平均 PHP 中多维数组的值。数组示例:

$t[1][1]=2;
$t[1][2]=3;
$t[2][1]=5;
$t[3]=6;
$t[4][1][1]=9;
$t[4][1][2]=10;
$t[4][2][1]=12;
$t[4][2][2]=13;

还要注意,父母没有价值(因为他们有孩子)。我有这个:

function chklevel($s) {
  $l = explode(".",$s);
}

这使我能够将 chklevel 称为

chklevel("4.2.2")

让它返回 13,但我也希望能够调用

chklevel("4")

并让它返回 11(这是 4.1.1(9)、4.1.2(10)、4.2.1(12) 和 4.2.2(13) 的平均值。

有什么想法吗?

【问题讨论】:

  • 当参数不是字符串时,如何调用chklevel(4.2.2)?这将引发错误。另外,函数 chklevel 还没有返回任何东西,这是故意的吗?也许我只是没有很好地回答你的问题。
  • 抱歉 - 已更正。我可以发誓我在那里有引号。此外,它更像是一个伪代码而不是真正的代码,因为我有一个 explode() 为我处理字符串。
  • 确保你看到我对答案的更新,我添加了一个数组检查(你的 4.2.2 示例给我带来了麻烦,因为一个数组没有传递(一个值是)所以 foreach 被炸了- - 但现在已经修好了)

标签: php recursion average


【解决方案1】:

我必须在两个函数中执行此操作(只是因为搜索的递归性质,但这是我的出价:

function mdarray_avg($array, $level = ''){
  if (!is_array($array)) throw new Exception("First argument must be an array");
  if (!is_string($level)) throw new Exception("Second argument must be string");

  $ary = $array;
  $levels = explode('.',$level);
  foreach ($levels as $lvl){
    if (array_key_exists($lvl,$ary))
      $ary = $ary[$lvl];
    else
      throw new Exception("Level {$level} doesn't exist");
  }

  $numbers = _mdarray_avg($ary);
  $sum = array_sum($numbers);
  return ($sum > 0 ? $sum / count($numbers) : 0);
}

function _mdarray_avg($array){
  if (!is_array($array)) return array($array);
  $numbers = array();
  foreach ($array as $element){
    if (is_array($element))
      $numbers = array_merge($numbers,_mdarray_avg($element));
    else
      $numbers[] = $element;
  }
  return $numbers;
}

像这样使用它:

echo "Average: ".mdarray_avg($t,'4'); // returns 11, as expected. 

$t 是要搜索的数组,'4' 是您要搜索的级别(也可以是 '1''4.2' 等。

另外,一个有趣的说明,免除第二个参数平均整个数组,在这种情况下我返回 7.5 (avg(2,3,5,6,9,10,12 ,13))

【讨论】:

  • 太棒了。谢谢。 :)
  • @tommyvallier:没问题。还添加了另一个针对无效级别的校验和(而不是静默跳过丢失的数组键,它会异常指出级别不存在 [以前使用 6.4.2 实际上会平均 4.2。它不会找到级别 6 , 会跳过,然后继续寻找 4])
【解决方案2】:

这是我的解决方案:

function chklevel($t) {

  for ($i = 1; $i < func_num_args(); $i++) {
    if (is_array($t) && isset($t[func_get_arg($i)]))
      $t = $t[func_get_arg($i)];
  }

  return GetAvg($t);
}

function GetAvg($arr) {

  if (is_array($arr)) {
    $avg = 0;
    foreach ($arr as $v) {
      $avg += GetAvg($v);
    }
    $avg /= count($arr);

  } else if (is_numeric($arr)) {
    $avg = $arr;
  }

  return $avg;
}

我更喜欢这样的函数调用:chklevel($t, 4,2,2);,但你可以很容易地为字符串修改它:

function chklevel($t, $s) {
  $indexes = explode(".", $s);
  for ($i = 0; $i < count($indexes); $i++) {
    if (is_array($t) && isset($t[$indexes[$i]]))
      $t = $t[$indexes[$i]];
  }

  return GetAvg($t);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-12
    相关资源
    最近更新 更多