我想按字段对关联数组进行分组。该数组本身最初来自mysql数据库查询。
以下是我如何通过硬编码来实现它的示例:
<?php
$fields = array("ID,subID");
$fieldCounts = count($fields);
$data = array(); //there is sql querieed data
$parsedData = array();
foreach ($data as $val)
{
if ($fieldCounts == 1)
{
$f0 = $fields[0];
$fv0 = $val[$f0];
$parsedData[$fv0][] = $val;
}
else if ($fieldCounts == 2)
{
$f0 = $fields[0];
$fv0 = $val[$f0];
$f1 = $fields[10];
$fv1 = $val[$f1];
$parsedData[$fv0][$f1][] = $val;
}
else
{
exit("Third field not implemented");
}
}
?>
但是我怎么能用任意数量的字段动态地做呢?
答案 0 :(得分:2)
我不确定这段代码是如何为你起作用的,但是有些东西是错的,可能不允许代码正常运行
字段只有一个值,
$fields = array("ID,subID");
^----------- between string
而不是
$fields = array("ID","subID");
注意:未定义的偏移量:
$f1 = $fields[10];
^----- your array is not up to 10
由于您没有放置生成数据和所需的输出。我会假设你的最终输出并生成一些临时数据
$fields = array("ID","subID"); //You can Increase or decrease this Fields
$fieldCounts = count($fields);
$data = array(); // there is sql querieed data
for($i = 0; $i < 3; $i ++) {
$data[] = array("ID" => mt_rand(1, 1000),"subID" => "sub" . mt_rand(100, 900));
}
使用上面的2个更正破坏您的代码
foreach ( $data as $val ) {
if ($fieldCounts == 1) {
$f0 = $fields[0];
$fv0 = $val[$f0];
$parsedData[$fv0][] = $val;
} else if ($fieldCounts == 2) {
$f0 = $fields[0];
$fv0 = $val[$f0];
$f1 = $fields[1];
$fv1 = $val[$f1];
$parsedData[$fv0][$f1][] = $val;
} else {
exit("Third field not implemented");
}
}
输出
Array
(
[159] => Array
(
[subID] => Array <----------- SubID is fixed in your can cause confict
(
[0] => Array
(
[ID] => 159
[subID] => sub589
)
)
)
[334] => Array
(
[subID] => Array
(
[0] => Array
(
[ID] => 334
[subID] => sub703
)
)
)
)
更好的替代方案
$parsedData = array();
foreach ( $data as $val ) {
$temp = &$parsedData;
foreach ( array_slice($val, 0, $fieldCounts) as $key ) {
$temp = &$temp[$key];
}
$temp[] = $val;
}
print_r($parsedData);
输出
Array
(
[159] => Array
(
[sub589] => Array <---------- Make Sub ID Dynamic
(
[0] => Array
(
[ID] => 159
[subID] => sub589
)
)
)
[334] => Array
(
[sub703] => Array
(
[0] => Array
(
[ID] => 334
[subID] => sub703
)
)
)
)
推荐版本简化阵列路径
$parsedData = array();
foreach ( $data as $val ) {
$temp = &$parsedData;
foreach ( array_slice($val, 0, $fieldCounts) as $key ) {
$temp = &$temp[$key];
}
$temp = $val;
}
print_r($parsedData);
输出
Array
(
[159] => Array
(
[sub589] => Array <---- Easy to asses as $parsedData['159']['sub589']
(
[ID] => 159
[subID] => sub589
)
)
[334] => Array
(
[sub703] => Array
(
[ID] => 334
[subID] => sub703
)
)
)
答案 1 :(得分:1)
而不是在你的$data
foreach循环中使用if / elseif / else(它总是限于你用那个结构编写的数字和大量的代码复制),你需要转向if / elseif / else进入它自己的循环。
但首先转换现有代码,我从第一个if主体开始,它包含已经所有必要代码:
$f0 = $fields[0];
$fv0 = $val[$f0];
$parsedData[$fv0][] = $val;
$val
应分配给由$parsedData
名称$fields
ue键控的数组$val
。我们在这里压缩它,名称中的数字0
是多余的,因为我们不再需要它(但可能是第一个):
$field = $fields[0];
$value = $values[$field];
$parsedData[$value][] = $values;
(我将$val
更改为$values
以改进命名)。现在更容易阅读和理解。我们也更容易在这里发现幻数0
。
现在到了魔法。我们想在这里添加一个数组(推送):
$parsedData[$value][] = $values;
为了让这更容易,让我们这样转过来:
$array = &$parsedData[$value];
$array[] = $values;
现在这似乎是多余的,但当这变成一个循环时,它会变得更加清晰:
$array = &$parsedData;
...
$array = &array[$value];
...
$array[] = $values;
让我们暂时回顾一下外循环的代码:
foreach ($data as $values)
{
$array = &$parsedData;
$field = $fields[0];
$value = $values[$field];
$array = &$array[$value];
$array[] = $values;
}
显然这段代码尚未完成。内循环缺失但它开始得到某种身体。实际上,内循环很容易实现:
$array = &$parsedData;
foreach ($fields as $field)
{
$value = $values[$field];
$array = &$array[$value];
}
$array[] = $values;
而且已经是这样了。单个字段已转换为所有字段的迭代。迭代中每个步骤的子数组的别名/引用允许在内部循环完成后将值推送到适当的数组条目。
整个外环和内环:
foreach ($data as $values)
{
$array = &$parsedData; # set reference
foreach ($fields as $field)
{
$value = $values[$field];
$array = &$array[$value];
}
$array[] = $values;
unset($array); # remove reference
}