我有一个如下所示的数据库表:
uid | group | category
1 | group1 | cat1
2 | group1 | cat2
3 | group2 | cat3
4 | group2 | cat4
5 | group2 | cat5
6 | group3 | cat6
7 | group3 | cat7
但是我需要在数组中使用这些数据,这些数据按照group
对类别进行分组。
例如,我的数组应如下所示:
Array
(
[group1] => Array
(
[0] => Array
(
[0] => 1
[1] => cat1
)
[1] => Array
(
[0] => 2
[1] => cat2
)
)
[group2] => Array
(
[0] => Array
(
[0] => 3
[1] => cat3
)
[1] => Array
(
[0] => 4
[1] => cat4
)
[2] => Array
(
[0] => 5
[1] => cat5
)
)
[group3] => Array
(
[0] => Array
(
[0] => 6
[1] => cat6
)
[1] => Array
(
[0] => 7
[1] => cat7
)
)
)
我已经编写了一个foreach循环,但是我有一个问题。
我的问题是它总是遗漏表格的最后一行,我不知道如何解决它。在我看来,逻辑规定它应该始终有效。
我想在循环之后我可以将最后一行添加到新数组中,但我认为如果最后一行有不同的组可能会导致问题,我宁愿将解决方案构建到foreach中循环。
不幸的是,我在这里不知所措。如何修复我的代码以包含数据库查询的最后一行?
我也有兴趣看看我可以对当前代码做出哪些改进,但对于代码审查来说这可能是一个更好的问题。
我的循环:
$pass = [];
foreach($stmt as $key => $value) {
if(empty($currentGroup)) $currentGroup = $value['group'];
if(empty($temp)) $temp = [];
if($currentGroup != $value['group'] || $key+1 == count($stmt)) {
$pass[$currentGroup] = $temp;
$currentGroup = $value['group'];
$temp = [];
$temp[] = [$stmt[$key]['uid'], $stmt[$key]['category']];
} else {
$temp[] = [$stmt[$key]['uid'], $stmt[$key]['category']];
}
}
答案 0 :(得分:3)
以下应该这样做:
<?php
//Create an array to store our grouped rows
$grouped = array();
//Loop over all rows returned by the $stmt that has been executed.
//You could probably remove the key from here, it's not needed it seems.
//The keys within the $value array will match the names of the columns in
//the database,
foreach($stmt as $key => $value){
//As we're storing by the group value from the row we first want to
//check if our grouped array contains a key for the group of the row
//being processed. If it does not, create an empty array within the
//grouped data for this group.
if(!array_key_exists($value['group'], $grouped)){
$grouped[$value['group']] = array();
}
//Knowing we will always have an array element for the rows group
//we can blindly append the values for this row to the grouped
//container using its values.
//'[] =' is just short hand append.
$grouped[$value['group']][] = array(
$value['uid'],
$value['category']
);
}
希望有所帮助!
为了进一步证明此循环,您可以将分组值附加更改为以下内容:
<?php
//Setting the whole row (minus the group) rather than just the uid
//and category explicitly allows this code to work without modification
//as the datatable changes, ie. new columns. Assuming that is the 'group'
//column remains present
unset($value['group']);
$grouped[$value['group']][] = $value;
现在可以使用以下方法访问分组内容数据:
<?php
//Acceess data via column name not array index, yay!
echo $grouped['group1']['uid']
答案 1 :(得分:0)
我最近又需要这个,所以我根据@JParkinson1991的答案做了一个函数。
我把它放在这里用于记录,并可能帮助未来的读者。
function groupArray($arr, $group, $preserveSubArrays = false, $preserveGroupKey = false) {
$temp = array();
foreach($arr as $key => $value) {
$groupValue = $value[$group];
if(!$preserveGroupKey)
{
unset($arr[$key][$group]);
}
if(!array_key_exists($groupValue, $temp)) {
$temp[$groupValue] = array();
}
if(!$preserveSubArrays){
$data = count($arr[$key]) == 1? array_pop($arr[$key]) : $arr[$key];
} else {
$data = $arr[$key];
}
$temp[$groupValue][] = $data;
}
return $temp;
}
function groupArray($arr, $group, $preserveGroupKey = false, $preserveSubArrays = false)
此功能接受2到4个参数。
第一个参数是数组本身,第二个参数是您要分组的键,第三个(可选)参数是一个布尔值,它告诉函数是否要保留子数组中的组键
$temp = array();
foreach($arr as $key => $value) {
$groupValue = $value[$group];
if(!$preserveGroupKey)
{
unset($arr[$key][$group]);
}
if(!array_key_exists($groupValue, $temp)) {
$temp[$groupValue] = array();
}
$temp[$groupValue][] = $arr[$key];
}
首先,我们创建一个名为$temp
接下来,我们遍历数组抓取键(应该是一个字符串或int),以及值(应该是一个数组)。
我们将$groupValue
设置为您选择的$group
的值,例如下面示例中的“group”。
$arr = [
0 => [
"group" => "group1",
"name" => "Bob",
],
1 => [
"group" => "group1",
"name" => "Randy",
],
2 => [
"group" => "group1",
"name" => "Susan",
],
3 => [
"group" => "group2",
"name" => "Larry",
],
4 => [
"group" => "group2",
"name" => "David",
],
5 => [
"group" => "group3",
"name" => "Perry",
],
];
然后我们检查是否要$preserveGroupKey
。如果此布尔值为false(并且默认情况下是这样),则将删除该键,留下几个仅包含“name”键的子数组。
现在我们检查$groupValue
数组中是否存在$temp
,如果不存在,我们会创建它。
然后我们将$temp[$groupValue]
添加到当前行值。从上面的例子中,我们最终得到:
Array
(
[group1] => Array
(
[0] => Bob
[1] => Randy
[2] => Susan
)
[group2] => Array
(
[0] => Larry
[1] => David
)
[group3] => Array
(
[0] => Perry
)
)
或者,将第3个参数设置为true,您将得到:
Array
(
[group1] => Array
(
[0] => Array
(
[name] => Bob
)
[1] => Array
(
[name] => Randy
)
[2] => Array
(
[name] => Susan
)
)
[group2] => Array
(
[0] => Array
(
[name] => Larry
)
[1] => Array
(
[name] => David
)
)
[group3] => Array
(
[0] => Array
(
[name] => Perry
)
)
)