2017-01-10 7 views
2

私は配列をキーに基づいてサブアレイにグループ化しようとしています。アレイをキーを使用してサブアレイにグループ化するにはどうすればよいですか?

サンプルアレイ

Array 
(
    [0] => Array 
     (
      [a_id] => 1 
      [a_name] => A1 
      [b_id] => 1 
      [b_name] => B1 
      [c_id] => 1 
      [c_name] => C1 
     ) 

    [1] => Array 
     (
      [a_id] => 1 
      [a_name] => A1 
      [b_id] => 1 
      [b_name] => B1 
      [c_id] => 2 
      [c_name] => C2 
     ) 

    [2] => Array 
     (
      [a_id] => 1 
      [a_name] => A1 
      [b_id] => 2 
      [b_name] => B2 
      [c_id] => 3 
      [c_name] => C3 
     ) 

    [3] => Array 
     (
      [a_id] => 2 
      [a_name] => A2 
      [b_id] => 3 
      [b_name] => B3 
      [c_id] => 4 
      [c_name] => C4 
     ) 

) 

私は、このサンプルの配列は、次の形式のJSON配列に変換する必要があります

予想される出力

[{ 
    "a_id": 1, 
    "a_name": "A1", 
    "b_list": [{ 
     "b_id": 1, 
     "b_name": "B1", 
     "c_list": [{ 
      "c_id": 1, 
      "c_name": "C1" 
     }, { 
      "c_id": 2, 
      "c_name": "C2" 
     }] 
    }, { 
     "b_id": 2, 
     "b_name": "B2", 
     "c_list": [{ 
      "c_id": 3, 
      "c_name": "C3" 
     }] 
    }] 
}, { 
    "a_id": 2, 
    "a_name": "A2", 
    "b_list": [{ 
     "b_id": 3, 
     "b_name": "B3", 
     "c_list": [{ 
      "c_id": 4, 
      "c_name": "C4" 
     }] 
    }] 
}] 

私ができました以下のコードを使用してキーでグループ化します。

$array = array(
array("a_id" => "1","a_name" => "A1","b_id" => "1","b_name" => "B1","c_id" => "1","c_name" => "C1"), 
array("a_id" => "1","a_name" => "A1","b_id" => "1","b_name" => "B1","c_id" => "2","c_name" => "C2"), 
array("a_id" => "1","a_name" => "A1","b_id" => "2","b_name" => "B2","c_id" => "3","c_name" => "C3"), 
array("a_id" => "2","a_name" => "A2","b_id" => "3","b_name" => "B3","c_id" => "4","c_name" => "C4") 
); 
$return = array(); 
foreach($array as $val) { 
    $return[$val["a_id"]][] = $val; 
} 
print_r($return); 

私の実際のシナリオでは、サブアレイにグループ化することは機能しませんでした。

期待されるJSONレスポンスを得るための最適な方法や便利な機能があるかどうかを楽しみにしています。

注:ここでは一般的な使用例を検討しています。たとえば、国としてはa_list、州としてはb_list、都市ではc_listです。

+0

あなたの入力と期待される出力をできるだけ小さくすることはできますか?それで、あなたが期待する行動を理解するのが簡単です。 –

+1

それは...むしろ面白く渦巻いています。 @TomasZubiriこれは、できるだけ小さなサンプルです。言うまでもなく、このグループには多くの詳細があります。 –

+2

@SurabhilSergyはい、いくつかありますが、今は時間がありません。それは何らかの再帰性を意味する。数時間で何かを試してみる –

答えて

2

非常に特定の配列のユースケースです。ここにあなたの解決策があります。

$array = <YOUR SAMPLE ARRAY> 
$output = []; 
/* 
* Nesting array based on a_id, b_id 
*/ 
foreach ($array as $item) { 
    $aid = $item['a_id']; 
    $bid = $item['b_id']; 
    $cid = $item['c_id']; 
    if(!isset($output[$aid])){ 
     $output[$aid] = [ 
      'a_id' => $item['a_id'], 
      'a_name' => $item['a_name'], 
      'b_list' => [ 
       $bid => [ 
        'b_id' => $item['b_id'], 
        'b_name' => $item['b_name'], 
        'c_list' => [ 
         $cid = [ 
          'c_id' => $item['c_id'], 
          'c_name' => $item['c_name'] 
         ] 
        ] 
       ] 
      ] 
     ]; 
    } else if (!isset($output[$aid]['b_list'][$bid])){ 
     $output[$aid]['b_list'][$bid] = [ 
      'b_id' => $item['b_id'], 
      'b_name' => $item['b_name'], 
      'c_list' => [ 
       $cid => [ 
        'c_id' => $item['c_id'], 
        'c_name' => $item['c_name'] 
       ] 
      ] 
     ]; 
    } else if(!isset($output[$aid]['b_list'][$bid]['c_list'][$cid])) { 
     $output[$aid]['b_list'][$bid]['c_list'][$cid] = [ 
      'c_id' => $item['c_id'], 
      'c_name' => $item['c_name'] 
     ]; 
    } else { 
     // Do/Dont overrider 
    } 
} 
/* 
* Removing the associativity from the b_list and c_list 
*/ 
function indexed($input){ 

    $output = []; 
    foreach ($input as $key => $item) { 
     if(is_array($item)){ 
      if($key == 'b_list' || $key == 'c_list'){ 
       $output[$key] = indexed($item); 
      } else { 
       $output[] = indexed($item); 
      } 
     } else { 
      $output[$key] = $item; 
     } 
    } 
    return $output; 
} 
$indexed = indexed($output); 
print_r(json_encode($indexed, 128)); 
0

これはかなり面白いです。あなたが知る限り、フラットな配列を多次元配列に変換するだけでなく、のキーを多次元表現に変換しようとしています。

a_*の下線より前の部分に最上位の違いがあるようです。

次に、これらのキーごとに、他のすべての*_文字がそれ自身のリストを誘導する必要があります。

この再帰関数は、ハードコーディングなしでトリックを行い、レベル、文字(またはその他のもの)と権利識別子の数に関係なく動作します。

コードで、あなたが深いY_するA_からインデックスのためにそれを使用することができます。ここ

$multidimension = multidimensionalify($array, ['a', 'b', 'c'], ['name']); 
var_dump(json_encode($multidimension, JSON_PRETTY_PRINT)); 

function multidimensionalify(
    array $input, 
    array $topLevelLetters, 
    array $rightHandIdentifiers, 
    $level = 0, 
    $parentId = null, 
    $uniqueString = 'id' 
) 
{ 
    $thisDimension = []; 
    $thisLetter = $topLevelLetters[$level]; 
    foreach ($input as $entry) 
    { 
     $thisId = $entry["{$thisLetter}_{$uniqueString}"]; 
     $condition = true; 
     if ($parentId !== null) 
     { 
      $parentLetter = $topLevelLetters[$level - 1]; 
      $condition = $entry["{$parentLetter}_{$uniqueString}"] === $parentId; 
     } 
     if (!isset($thisDimension[$thisId]) && $condition) 
     { 
      $thisObject = new stdClass; 
      $thisObject->{"{$thisLetter}_{$uniqueString}"} = $thisId; 
      foreach ($rightHandIdentifiers as $identifier) 
      { 
       $thisObject->{"{$thisLetter}_{$identifier}"} = $entry["{$thisLetter}_{$identifier}"]; 
      } 
      if (isset($topLevelLetters[$level + 1])) { 
       $nextLetter = $topLevelLetters[$level + 1]; 
       $thisObject->{"{$nextLetter}_list"} = multidimensionalify($input, $topLevelLetters, $rightHandIdentifiers, $level + 1, $thisId, $uniqueString); 
      } 
      $thisDimension[$thisId] = $thisObject; 
     } 
    } 
    return array_values($thisDimension); 
} 
1

(あなたの質問に定義されているよう$arrayが配列されて)あなたがサンプルで示し正確にJSONを返すように思えます。あなたがそれを望まないなら、innerest要素はnullです。最後の要素の前にforループを終了し、最後の要素を別々に処理します。また、このコードを改善することもできます。お役に立てれば。

<?php 
    $array = array(
    array("a_id" => "1","a_name" => "A1","b_id" => "1","b_name" => "B1","c_id" => "1","c_name" => "C1"), 
    array("a_id" => "1","a_name" => "A1","b_id" => "1","b_name" => "B1","c_id" => "2","c_name" => "C2"), 
    array("a_id" => "1","a_name" => "A1","b_id" => "2","b_name" => "B2","c_id" => "3","c_name" => "C3"), 
    array("a_id" => "2","a_name" => "A2","b_id" => "3","b_name" => "B3","c_id" => "4","c_name" => "C4") 
    ); 
    $arrays = array_map(function($v){return array_chunk($v, 2, true);}, $array); 
    $result = []; 
    foreach($arrays as $value) 
    { 
     $ref = &$result; 
     $len = count($value); 
     $index = 0; 
     for(; $index < $len; $index++) 
     { 
      $arr = $value[$index]; 
      $char = key($arr)[0]; 
      $charAdd = chr(ord($char)+1); 
      $key = $arr[$char.'_id'].$arr[$char.'_name']; 
      $listKey = $charAdd.'_list'; 
      foreach($arr as $k => $v) 
      { 
       $ref[$key][$k] = $v; 
      } 
      $ref = &$ref[$key][$listKey]; 
     } 
    } 
    var_dump($result); 

出力:live demo

[email protected]:~$ php test.php 
array(2) { 
    ["1A1"]=> 
    array(3) { 
    ["a_id"]=> 
    string(1) "1" 
    ["a_name"]=> 
    string(2) "A1" 
    ["b_list"]=> 
    array(2) { 
     ["1B1"]=> 
     array(3) { 
     ["b_id"]=> 
     string(1) "1" 
     ["b_name"]=> 
     string(2) "B1" 
     ["c_list"]=> 
     array(2) { 
      ["1C1"]=> 
      array(3) { 
      ["c_id"]=> 
      string(1) "1" 
      ["c_name"]=> 
      string(2) "C1" 
      ["d_list"]=> 
      NULL 
      } 
      ["2C2"]=> 
      array(3) { 
      ["c_id"]=> 
      string(1) "2" 
      ["c_name"]=> 
      string(2) "C2" 
      ["d_list"]=> 
      NULL 
      } 
     } 
     } 
     ["2B2"]=> 
     array(3) { 
     ["b_id"]=> 
     string(1) "2" 
     ["b_name"]=> 
     string(2) "B2" 
     ["c_list"]=> 
     array(1) { 
      ["3C3"]=> 
      array(3) { 
      ["c_id"]=> 
      string(1) "3" 
      ["c_name"]=> 
      string(2) "C3" 
      ["d_list"]=> 
      NULL 
      } 
     } 
     } 
    } 
    } 
    ["2A2"]=> 
    array(3) { 
    ["a_id"]=> 
    string(1) "2" 
    ["a_name"]=> 
    string(2) "A2" 
    ["b_list"]=> 
    array(1) { 
     ["3B3"]=> 
     array(3) { 
     ["b_id"]=> 
     string(1) "3" 
     ["b_name"]=> 
     string(2) "B3" 
     ["c_list"]=> 
     array(1) { 
      ["4C4"]=> 
      array(3) { 
      ["c_id"]=> 
      string(1) "4" 
      ["c_name"]=> 
      string(2) "C4" 
      ["d_list"]=> 
      &NULL 
      } 
     } 
     } 
    } 
    } 
} 
+0

こんにちは、downvoter、あなたの理由をここで分かち合えますか? –

+0

あなたの解決策はちょっと不思議で、最後のエントリーを別々に処理する必要があります。それは達成可能なレベルの数に(非常に高い)制限を持っています。私が知る限り、実際にopで提案されたサンプルを実際に返す唯一の解決策です。深さの制限はなく、レベル数とキー値ペアの両方で保持され、これらのパラメータを実際にパラメータ化できますキー。他のすべての人はハードコーディングされたキーと非再帰的な動作を持っています。 –

+0

@FélixGagnon-Grenier私はあなたが答えが良いと思っていないのは、他の人を落とす理由です。 –

2

興味深い要件がオンライン。 拡張可能な私の一般化されたソリューションがここにあります。このソリューションを拡張するために

function transform($array, $group=[ 
    ['a_id','a_name','b_list'], 
    ['b_id','b_name','c_list'], 
    ['c_id','c_name'], 
]){ 
    foreach($array as $a){ 
     $r = &$result; 
     foreach($group as $g){ 
      $x = &$r[$a[$g[0]]]; 
      $x[$g[0]] = $a[$g[0]]; 
      $x[$g[1]] = $a[$g[1]]; 
      if(isset($g[2])) $r = &$x[$g[2]]; else break; 
     } 
    } 
    return transformResult($result); 
} 

function transformResult($result){ 
    foreach($result as &$a) 
     foreach($a as &$b) 
      if(is_array($b)) $b = transformResult($b); 
    return array_values($result); 
} 

、あなたがしなければならないすべては、直接、関数宣言または第二パラメータとして適切な値を渡すことで、どちらか$groupパラメータ、 を変更しています。

使用例:

echo json_encode(transform($array), JSON_PRETTY_PRINT); 

これはあなたの例では、同じ$array入力を想定して同じ出力を返します。

2

ここでは、特定の状況で最も効果的なコードを示します。私は同様の状況を作り、その解決策を詳細に説明しました。


オーダーフォーム状況
は、選択したパッケージに基づい務めた日数に応じて、複数ページです。各パッケージの詳細は、以下のフィールドを持つデータベースに格納されています。日中

  1. PACKAGE_ID(一意のフィールド)
  2. パッケージ名(パッケージの名前、例えばパッケージA)
  3. servings_count(合計食分)毎日の食事の選択を前進させるためには
  4. days_served(月に従軍日数)

とダでの注文として保存するために、その日のサービス提供私はダイナミックに定義/投入できるPHPの多次元配列が必要でした。

Array 
(
    [Day 1] => Array 
     (
      [meal_id_1] => Unique ID //to be replaced with user selection 
      [meal_code_1] => Meal Name //to be replaced with user selection 
      [meal_type_1] => Meal //prefilled based on the selected package 
      [meal_id_2] => Not Available //to be replaced with user selection 
      [meal_code_2] => 2 //to be replaced with user selection 
      [meal_type_2] => Meal //prefilled based on the selected package 
     ) 

    [Day 2] => Array 
     (
      [meal_id_1] => Unique ID //to be replaced with user selection 
      [meal_code_1] => Meal Name //to be replaced with user selection 
      [meal_type_1] => Meal //prefilled based on the selected package 
      [meal_id_2] => Not Available //to be replaced with user selection 
      [meal_code_2] => 2 //to be replaced with user selection 
      [meal_type_2] => Meal //prefilled based on the selected package 
     ) 

これ以上の配列は人前と日の説明構造および数に基づいて動的に100%に作成されています:

の予想される出力は次のようなものです。以下はいくつかの説明があるコードです。

まず、2つのPHP配列を宣言する必要があります。

$total_meals_array = []; //Primary, Multidimension Array 
$meals_selected_array = []; //Meals Details Array to be used as primary array's key value. 

これを実行した後、MySQLクエリを実行してデータベースからパッケージを読み取ります。結果に基づいて、以下を実行してください:

$total_meals_array = []; //Primary, Multidimension Array 
$meals_selected_array = []; //Meals Details Array to be used as primary array's key value. 

if($num_row_packages >= 1) { 
    while($row_packages = mysqli_fetch_array ($result_packages)) { 
     $package_id = $row_packages['package_id']; 
     $package_name = $row_packages['package_name']; 
     $servings_count = $row_packages['servings_count']; 
     $days_served = $row_packages['days_served']; 

     //this for loop is to repeat the code inside `$days_served` number of times. This will be defining our primary and main Multidimensional Array `$total_meals_array`. 
     for ($y = 1; $y <= $days_served; $y++) { 
      //once inside the code, now is the time to define/populate our secondary array that will be used as primary array's key value. `$i`, which is the meal count of each day, will be added to the key name to make it easier to read it later. This will be repeated `$meals_count` times. 

      for ($i = 1; $i <= $meals_count; $i++) { 
       $meals_selected_array["meal_id_" . $i] = "Unique ID"; 
       $meals_selected_array["meal_code_" . $i] = "Meal Name"; 
       $meals_selected_array["meal_type_" . $i] = "Meal"; 
      } 

      //once our secondary array, which will be used as the primary array's key value, is ready, we will start defining/populating our Primary Multidimensional Array with Keys Named based on `$days_served`. 
      $total_meals_array["Day " . $y] = $meals_selected_array; 
     } 
    } 
} 

これはそれです!私たちのダイナミックな多次元配列は準備ができていると単純に以下のコードで見ることができます。

print "<pre>"; 
print_r($total_meals_array); 
print "</pre>"; 

、あなたに親切にも私の質問に答えるためにあることのために特別に@yarwestをみんなにありがとうございます。

0

グループ化のために配列とキー名を渡し、jsonに変換するだけでこの関数を試してみてください。

public function _group_by($array, $key) { 
    $return = array(); 
    foreach ($array as $val) { 
     $return[$val[$key]][] = $val; 
    } 
    return $return; 
} 
関連する問題