簡體   English   中英

在PHP中按多個字段動態分組數據

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM