0

連想配列をフィールドごとにグループ化したい。配列自体は、もともと 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");
    }
}
?>

しかし、任意の数のフィールドで動的に行うにはどうすればよいでしょうか?

4

2 に答える 2

2

このコードがどのように機能したかはわかりませんが、いくつかの点が間違っていて、コードが正しく機能しない可能性があります

  • フィールドには、値が 1 つしかありません,

    $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
                )

        )

)
于 2012-10-26T14:49:49.510 に答える
1

foreachループ内でif/elseif / elseを実行する代わりに$data(これは常に、その構造と多くのコード重複を使用してそこに「書き込む」数に制限されます)、if / elseif/elseをに変換する必要があります。それ自身のループ。

しかし、最初に既存のコードを変換します。最初のif本体から始めます。これには、必要なすべてのコードがすでに含まれています。

$f0  = $fields[0];
$fv0 = $val[$f0];
$parsedData[$fv0][] = $val;

は、名前ueでキー設定され$valた配列に割り当てる必要があります。これをここで圧縮してみましょう。名前の数は、もう必要ないので不要です(ただし、最初の数かもしれません)。$parsedData$fields$val0

$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
}
于 2012-10-26T11:33:17.340 に答える