我有以下$test
数组,按' date '和' site '排序。
$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
中的索引是可选的(即不必要)。
我发现了这个类似的帖子(和其他人),但我不明白如何实现。 Getting all the related ones based on value
我已经尝试了很多不同的方式,我的头在旋转,非常感谢任何帮助!
答案 0 :(得分: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)
答案 1 :(得分: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"
}
}
答案 2 :(得分: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;
}
}
这样可以保留您遇到的第一个行ID,但可能无法进行特别优化。