2016-08-10 2 views
2

'tax'と 'concept'とSUM属性 'val'で配列をグループ化する方法は?プロパティ別に配列オブジェクトをグループ化する

私は、税金とコンセプトが同じ場合に単一のオブジェクトを作成したいと考えています。また、valをSUMします。

私は簡単なforeachと妥当性検査を試みましたが、動作しませんでした。

ありがとうございました。

echo json_encode($array); 

アレイプリント

[ 
{ 
    "tax": "10", 
    "concept": "TUC", 
    "val": "10" 
}, 
{ 
    "tax": "10", 
    "concept": "TUC", 
    "val": "86" 
}, 
{ 
    "tax": "15", 
    "concept": "TUC", 
    "val": "8" 
}, 
{ 
    "tax": "11", 
    "concept": "IPS", 
    "val": "6" 
}, 
{ 
    "tax": "11", 
    "concept": "IPS", 
    "val": "45" 
} 
] 

期待される結果

[ 
{ 
    "tax": "10", 
    "concept": "TUC", 
    "val": "96" 
}, 
{ 
    "tax": "15", 
    "concept": "TUC", 
    "val": "8" 
}, 
{ 
    "tax": "11", 
    "concept": "IPS", 
    "val": "51" 
} 
] 
+3

*私は簡単なforeachと内部で検証を試みましたが、動作しませんでした。 - コードを表示してください – splash58

答えて

3

あなたはここにarray_reduce()を使用することができます。グループ化するキーにはtaxの値を使用し、合計値はvalの値を同時に生成しながら、配列を一意のtax要素に減らします。このアプローチの唯一の注意点は、JSONに変換すると、外側の要素が配列ではなくオブジェクトであるとPHPは考えるようになります(配列ではないにしても、これはデフォルト以外の配列インデックスを使用するためです)。しかし、これは簡単にarray_values()への呼び出しで緩和されます。

$array = // your array from above 
$result = array_reduce($array, function($carry, $item) { 
    if(!isset($carry[$item->tax])) { 
     $carry[$item->tax] = $item; 
    } else { 
     $carry[$item->tax]->val += $item->val; 
    } 
    return $carry; 
}); 

$result = array_values($result); 

echo json_encode($result); 

あなたはそれが生成するthis demoから見ることができます。

$groups = []; 
foreach($array as $object){ 
    $groups[$object->tax . "\0" . $object->concept] = $object; 
    // I use the NUL byte to delimit, assuming it is absent in $tax and $concept 
} 

その後合算アップオブジェクトに各グループをマップ:オブジェクトは

[{ 
    "tax": "10", 
    "concept": "TUC", 
    "val": 96 
}, { 
    "tax": "15", 
    "concept": "TUC", 
    "val": "8" 
}, { 
    "tax": "11", 
    "concept": "IPS", 
    "val": 51 
}] 
+0

私にとってはうまくいきません。また、あなたは '税金 'の価値をキー。 OPは、**「税」と「コンセプト」の両方が同じであるときにグループ化したいので、キーはそれらの2つの組み合わせである必要があります。 –

+1

@VicenteOlivertRiera - そのためデモリンクがあり、試してみるとうまくいくことがわかります。また、OPのデータには、そのキーが必要な場合の値はありません(税金が別の要素と一致する場合、コンセプトも同じです)。しかし、簡単な変更でOPに実装することができます。 – nickb

0

まずグループを。

$output = array_map(function(array $group){ 
    $object = new stdClass; 
    $object->tax = $group[0]->tax; 
    $object->concept = $group[0]->concept; 
    $object->val = array_reduce($group, function($carry, $item){ 
     return $carry + $item->val; 
    }, 0); 
    return $object; 
}, $groups); 
0

二つのオブジェクトの税と概念の特性が等しく、それらのオブジェクトごとにこの番号に「ヴァル」プロパティを設定し、すべての「ヴァル」のアップを追加します。擬似コードで

はそれだけで、アレイ内の重複を削除このの終わりに...

//Loop through all elements of array starting at 0 
    //InnerLoop through all elements of array starting at 0 
     //test if outer and inner object have equivalent tax and concept properties (and aren't the same location) 
      //if so then add inner loop object's val to outer loop object's val 

ようになり、これは...のようになります

//Loop through all elements of array starting at the end and going to 0 
    //InnerLoop through all elements of array starting at 1 less than outer loop going to 0 
     //test if inner and outer loop object's have equal tax and concept properties 
      //if so then delete the object at the inner loops location 
0
<?php 
$arr_str = '[ 
    {"tax":"10", "concept":"TUC", "val":"10"}, 
    {"tax":"10", "concept":"TUC", "val":"86"}, 
    {"tax":"15", "concept":"TUC", "val":"8"}, 
    {"tax":"11", "concept":"IPS", "val":"6"}, 
    {"tax":"11", "concept":"IPS", "val":"45"} 
]'; 

$arr = json_decode($arr_str); 

$tmp_array = []; 

foreach ($arr as $e) { 
    // combine "tax" and "concept" so we can use both of them as key. Use "_" as delimiter. 
    $key = $e->tax . "_" . $e->concept; 
    // sum the "val" if the key exists, otherwise assign it 
    isset($tmp_array[$key]) ? $tmp_array[$key] += $e->val : $tmp_array[$key] = $e->val; 
} 

$grouped_array = []; 

foreach ($tmp_array as $k => $v) { 
    // ungroup the key so we can create an array like the original one 
    $tmp = explode("_", $k); 
    $grouped_array[] = (object)["tax" => $tmp[0], "concept" => $tmp[1], "val" => $v]; 
} 

echo json_encode($grouped_array); 
?> 
1
$array // Your array 
$result = []; 

array_walk($array, function($object) use (&$result) { 
    $notExist = true; 
    foreach ($result as $item) { 
     if ($item->tax == $object->tax && $item->concept == $object->concept) { 
      $item->val += $object->val; 
      $notExist = false; 
      break; 
     } 
    } 
    if ($notExist) { 
     array_push($result, $object); 
    } 
}); 

echo json_encode($result); 
関連する問題