php在2维数组中找到max但返回数组的另一个元素('id')

时间:2011-08-05 12:49:21

标签: php multidimensional-array mapreduce max

这是我的数组样本$data[][];

Array( [0] => Array ( [id] => 1349
                      [rating1] => 1.9378838029981E-7
                      [rating2] => 1.1801796607774     )
       [1] => Array ( [id] => 1350
                      [rating1] => 5.5499981876923E-7
                      [rating2] => 1.5121329727308     )
       [2] => Array ( [id] => 1377
                      [rating1] => 0.00023952225410117
                      [rating2] => 2.1947077830236     )
       [3] => Array ( [id] => 1378
                      [rating1] => 0.00022982302863634
                      [rating2] => 2.2135588326622     )
       [4] => Array ( [id] => 1379
                      [rating1] => 0.00026272979843585
                      [rating2] => 2.2388295595073     )
       [5] => Array ( [id] => 1380
                      [rating1] => 0.0002788640872546
                      [rating2] => 2.1815325502993     )
)

我想查找max($data[][rating?]),但返回$data[id][max_rating?],即idmax值相关联的rating1。 找到一个特定的最大值很容易,比如$max = array_reduce($data, function($a, $b) { return $a > $b['rating1'] ? $a : $b['rating1']; }); ,我使用了如下的array_reduce(这是受this SO的启发):

max

现在我有两个问题:
1.如何在array_reduce上方扩展以包含rating2?我也有其他评级。
2.我不希望$data[][id]值,而是与max关联的$data[][id]

我并不关心Q1,但第二个很重要,因为我不想再次搜索数组以获得关联[id]。 一种思路是使用array_map而不是array_reduce,但我无法想出一个将传递[rating?]max()的版本。此外,当我一次尝试rating?多个max时,会出现并发症,因为每个评分会有不同的[id],而后者会与不同的id相关联。 /> 编辑:为了清楚起见,我希望所有相应的max与每个rating?

的{{1}}相关联

2 个答案:

答案 0 :(得分:1)

假设您的数组未排序,您必须至少循环一次(手动或使用内置函数)。我使用以下代码:

$array = array(
  array( 'id' => 1349, 'sudhi_rating1' => 1.9378838029981E-7, 'sudhi_rating2' => 1.1801796607774 ),
  array( /* … */ ),
  /* … */
);

$idx_max = 0;
foreach($array as $idx => $item) {
  if($item['sudhi_rating1'] > $array[$idx_max]['sudhi_rating1'])
    $idx_max = $idx;
}

echo "Rating 1 has max value at id ", htmlspecialchars($array[$idx_max]['id']);

您可以扩展代码以一次检查多个评级(让$idx_max成为一个数组本身并添加更多ifs):

$idx_max = array (
  'sudhi_rating1' => 0,
  'sudhi_rating2' => 0,
  /* … */ );
foreach($array as $idx => $item) {
  foreach($idx_max as $rating => &$max) {
    if($item[$rating] > $array[$max][$rating])
      $max = $idx;
  }
}

foreach($idx_max as $rating => $max)
  echo 'Max value for ', htmlspecialchars($rating), ' has id ', htmlspeciachars($array[$max]['id']);

答案 1 :(得分:1)

$max = array_reduce($data, function($a, $b) {    
  if (is_null($a)) return $b;
  return max($a['rating1'],$a['rating2'])>max($b['rating1'],$b['rating2']) ? $a : $b;
});

结果:没有条目$max= NULL,否则$max['id']是具有最高评级的ID

或者这个通用代码

$max = array_reduce($data, function($a, $b) {
   if (is_null($a)) return $b;
   return maxRating($a)>maxRating($b) ? $a : $b;
 });

function maxRating($row){
   return (max(array_intersect_key($row,array_flip(array_filter(array_keys($row),function ($item) { return strstr($item,'rating')!==FALSE;})))));
}

会找到表单评级的所有评级吗?

编辑 - 代码试图回答Q1这里只是Q2的答案

$max = array_reduce($data, function($a, $b) {    
  if (is_null($a)) return $b;
  return $a['rating1']>$b['rating1'] ? $a : $b;
});

EDIT2 - 这是任何评级的通用解决方案?列

$ratingKeys=array_filter(array_keys($data[0]),function ($item) { return strstr($item,'rating')!==FALSE;});

$max = array_reduce($data,function($a,$b) use (&$ratingKeys) {
  if (is_null($a)) {
    $a=array();
    foreach($ratingKeys as $key) {
      $a[$key]=$b[$key];
      $a[$key.'_id'] = $b['id'];
     }
     return $a;
  }
  foreach($ratingKeys as $key) {
    if ($a[$key]<$b[$key]) {
      $a[$key]=$b[$key];
      $a[$key.'_id']=$b['id'];
    }
  }
  return $a;
});

此代码导致

array(4) {
  ["rating1"]=> float(0.0002788640872546)
  ["rating1_id"]=> int(1380)
  ["rating2"]=> float(2.2388295595073)
  ["rating2_id"]=> int(1379)
}

编辑3 - 如果更改输入数组的格式以使用id作为数组键,则可以大规模简化

$max=array_reduce(array_keys($data),function ($a,$b) use (&$data) {
  if (is_null($a)) $a=array();
    foreach(array_keys($data[$b]) as $item) {
      if (!isset($a[$item]) {
        $a[$item] = $b;
      } else {
        if ($data[$a[$item]][$item]) < $data[$b][$item]) $a[$item]=$b;
      }
    return $a;
  }
});

此代码导致

array(2) {
  ["rating1"]=> int(1380)
  ["rating2"]=> int(1379)
}