[英]Group data by multiple fields dynamically in PHP
我想按字段分組關聯數組。 數組本身最初來自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");
}
}
?>
但是,如何動態地使用任意數量的字段呢?
不確定此代碼如何為您工作,但有些錯誤是錯誤的,可能使代碼無法正常運行
字段僅具有,
$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
)
)
)
而不是在$data
foreach循環內執行if / elseif / else(它總是限於您在其中使用該結構“寫”的數字和大量代碼重復),您需要將if / elseif / else進入自己的循環。
但是首先要轉換現有的代碼,首先從if主體開始,它已經包含了所有必需的代碼 :
$f0 = $fields[0];
$fv0 = $val[$f0];
$parsedData[$fv0][] = $val;
$val
應該分配給數組$parsedData
,該數組由$fields
name $val
ue鍵控。 讓我們在這里壓縮一下,名稱中的數字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
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.