3

我有下面的$test数组按“日期”和“网站”排序。

$test = array ( 
0 => array ( 
       'id' => '45', 
       'rating' => 'p1', 
       'site' => 'Heavener SW', 
       'time' => '11-03-2012 Sat 10:00:00', 
       ), 
1 => array ( 
       'id' => '45', 
       'rating' => 'h3', 
       'site' => 'Heavener SW', 
       'time' => '11-03-2012 Sat 10:00:00', 
       ),
2 => array ( 
       'id' => '45', 
       'rating' => 'h4', 
       'site' => 'Heavener SW', 
       'time' => '11-03-2012 Sat 16:00:00', 
       ),
3 => array ( 
       'id' => '110', 
       'rating' => 'p3', 
       'site' => 'Red Oak', 
       'time' => '11-03-2012 Sat 16:00:00', 
       ), 
4 => array ( 
       'id' => '110', 
       'rating' => 'h3', 
       'site' => 'Red Oak', 
       'time' => '11-03-2012 Sat 16:00:00', 
       ), 
5 => array ( 
       'id' => '32', 
       'rating' => 'p2', 
       'site' => 'Panopoint', 
       'time' => '11-04-2012 Sun 10:00:00', 
       ) 
 );

我已经疯了,试图为每个“站点”-“时间”组合组合“评级”。

$result = array (
0 => array ( 
       'id' => '45', 
       'rating' => 'p1, h3', 
       'site' => 'Heavener SW',
       'time' => '11-03-2012 Sat 10:00:00', 
       ),
2 => array ( 
       'id' => '45', 
       'rating' => 'h4', 
       'site' => 'Heavener SW', 
       'time' => '11-03-2012 Sat 16:00:00', 
       ),
3 => array ( 
       'id' => '110', 
       'rating' => 'p3, h3', 
       'site' => 'Red Oak', 
       'time' => '11-03-2012 Sat 16:00:00', 
       ),
5 => array ( 
       'id' => '32', 
       'rating' => 'p2', 
       'site' => 'Panopoint', 
       'time' => '11-04-2012 Sun 10:00:00', 
       ) 
 );

一个站点可以拥有的“评级”数量或有多少“站点”或“时间”没有限制(在合理范围内)。在 中保留索引$result是可选的(即不是必需的)。

我发现了这个类似的帖子(和其他帖子),但我不明白如何实现。 根据价值获取所有相关的

我已经尝试了很多不同的方式,我的头在旋转,非常感谢任何帮助!

4

3 回答 3

2

你可以简单地使用array_reduce

$test = array_reduce($test, function ($a, $b) {
    isset($a[$b['time'] . "|" . $b['id']]) ? $a[$b['time'] . "|" . $b['id']]['rating'] .= "," . $b['rating'] : $a[$b['time'] . "|" . $b['id']] = $b;
    return $a;
});

$test = array_values($test);
var_dump($test);

输出

array
  0 => 
    array
      'id' => string '45' (length=2)
      'rating' => string 'p1,h3' (length=5)
      'site' => string 'Heavener SW' (length=11)
      'time' => string '11-03-2012 Sat 10:00:00' (length=23)
  1 => 
    array
      'id' => string '45' (length=2)
      'rating' => string 'h4' (length=2)
      'site' => string 'Heavener SW' (length=11)
      'time' => string '11-03-2012 Sat 16:00:00' (length=23)
  2 => 
    array
      'id' => string '110' (length=3)
      'rating' => string 'p3,h3' (length=5)
      'site' => string 'Red Oak' (length=7)
      'time' => string '11-03-2012 Sat 16:00:00' (length=23)
  3 => 
    array
      'id' => string '32' (length=2)
      'rating' => string 'p2' (length=2)
      'site' => string 'Panopoint' (length=9)
      'time' => string '11-04-2012 Sun 10:00:00' (length=23)

观看现场演示

于 2012-11-03T23:41:36.860 回答
1

由于保留键是可选的,因此一个简单的选择是构建一个由唯一对键控的新数组,site|time同时遍历原始数组。

对于其中的每一个,我们还将创建一个rating值数组,最后,implode()将该数组转换为返回'ratings'键的字符串。

$rekeyed = array();
foreach ($test as $item) {
  // Build temporary key by concatenating site, time
  $key = $item['site'] . '|' . $item['time'];
  // If it already exists, add to the ratings
  if (isset($rekeyed[$key])) {
    $rekeyed[$key]['ratings'][] = $item['rating'];
  }
  else {
    // Otherwise, set the key and the ratings array
    $rekeyed[$key] = $item;
    // And set the first rating, initialized as an array
    $rekeyed[$key]['ratings'] = array();
    $rekeyed[$key]['ratings'][] = $item['rating'];
  }
}

// Finally, loop over and implode all the ratings back into a comma-separated string
foreach ($rekeyed as &$item) {
  $item['rating'] = implode(',', $item['ratings']);
  // Don't need the 'ratings' array anymore, unset it
  unset($item['ratings']);
}

var_dump($rekeyed);

输出:

array(4) {
  ["Heavener SW|11-03-2012 Sat 10:00:00"]=>
  array(5) {
    ["id"]=>
    string(2) "45"
    ["rating"]=>
    string(5) "p1,h3"
    ["site"]=>
    string(11) "Heavener SW"
    ["time"]=>
    string(23) "11-03-2012 Sat 10:00:00"
  }
  ["Heavener SW|11-03-2012 Sat 16:00:00"]=>
  array(5) {
    ["id"]=>
    string(2) "45"
    ["rating"]=>
    string(2) "h4"
    ["site"]=>
    string(11) "Heavener SW"
    ["time"]=>
    string(23) "11-03-2012 Sat 16:00:00"
  }
  ["Red Oak|11-03-2012 Sat 16:00:00"]=>
  array(5) {
    ["id"]=>
    string(3) "110"
    ["rating"]=>
    string(5) "p3,h3"
    ["site"]=>
    string(7) "Red Oak"
    ["time"]=>
    string(23) "11-03-2012 Sat 16:00:00"
  }
  ["Panopoint|11-04-2012 Sun 10:00:00"]=>
  &array(5) {
    ["id"]=>
    string(2) "32"
    ["rating"]=>
    string(2) "p2"
    ["site"]=>
    string(9) "Panopoint"
    ["time"]=>
    string(23) "11-04-2012 Sun 10:00:00"
  }
}
于 2012-11-03T23:31:08.627 回答
0

我认为 PHP foreach 循环按顺序进行,所以这应该有效。我还没有测试它,所以让我知道它是怎么回事。

$previous_id = '';
// for each row, check if it was the same as the previous row (since you have sorted it properly)
foreach($result as $k => $row){
    // if it matches the previous, add the rating and remove now duplicate row
    if ($row['time'] == $result[$previous_id]['time']
     && $row['site'] == $result[$previous_id]['site']){
        $result[$previous_id]['rating'] .= ', '.$row['rating'];
        unset($result[$k]);
    } // otherwise, set new previous_id to check
    else {
        $previous_id = $k;
    }
}

这具有保留您遇到的第一个 row-id 的额外好处,但可能没有特别优化。

于 2012-11-03T23:33:03.903 回答