0

私の配列は次のようなものです:

array(  
    (int) 0 => array(
    'projet_id' => '1',
    'activite_id' => '1',
    'domaine_id' => null,
    'aretirer' => (float) 4
),  
(int) 1 => array(
        'projet_id' => '1',
        'activite_id' => '3',
        'domaine_id' => null,
        'aretirer' => (float) 1
    ),  
(int) 2 => array(
        'projet_id' => '1',
        'activite_id' => '1',
        'domaine_id' => null,
        'aretirer' => (float) 2
    ),  
(int) 3 => array(
        'projet_id' => '1',
        'activite_id' => '3',
        'domaine_id' => null,
        'aretirer' => (float) 2
    )
)

projet_id、activite_id、および domaine_id が同じである aretirer キーを合計したい

foreach で試してみましたが、このような良い結果が得られませんでした

array(  
(int) 0 => array(
        'projet_id' => '1',
        'activite_id' => '1',
        'domaine_id' => null,
        'aretirer' => (float) 6
    ),  
(int) 1 => array(
        'projet_id' => '1',
        'activite_id' => '3',
        'domaine_id' => null,
        'aretirer' => (float) 3
    )
)

それが私がやろうとしたことです

public function array_sum($array){
    $arrayfusion=array();
    $i=0;
    foreach($array as $item):
        $arrayfusion[$i]['projet_id']=$item['projet_id'];
        $arrayfusion[$i]['activite_id']=$item['activite_id'];
        $arrayfusion[$i]['domaine_id']=$item['domaine_id'];   
        $arrayfusion[$i]['aretirer']=$item['aretirer']; 
        foreach($array as $itemnext):
            if($itemnext['projet_id']==$item['projet_id'] && $itemnext['activite_id']==$item['activite_id'] && $itemnext['domaine_id']==$item['domaine_id']):
                $arrayfusion[$i]['aretirer']+=$itemnext['aretirer']; 
            endif;
        endforeach;
        $i++;
    endforeach;
    return $arrayfusion;
}

ご協力いただきありがとうございます

4

3 に答える 3

0

あなたの答えでは、 $item['flag'] をチェックしていますが、設定していません。したがって、最初に内側のループ内に設定する必要があります。ただし、そのためには、配列要素を変更できる必要があります。

foreach($array as $itemnext):
  if($itemnext['projet_id']==$item['projet_id'] && $itemnext['activite_id']==$item['activite_id'] && $itemnext['domaine_id']==$item['domaine_id']):
    $arrayfusion[$i]['aretirer']+=$itemnext['aretirer']; 
    $itemnext['flag'] = true;
  endif;
endforeach;

内部コードにはオリジナルではなく $itemnext のコピーがあるため、機能しません。したがって、次のように配列に直接設定する必要があります。

foreach($array as $key => $itemnext):
  if($itemnext['projet_id']==$item['projet_id'] && $itemnext['activite_id']==$item['activite_id'] && $itemnext['domaine_id']==$item['domaine_id']):
    $arrayfusion[$i]['aretirer']+=$itemnext['aretirer']; 
    $array["$key"]['flag'] = true;
  endif;
endforeach;

または、次のように foreach を開始して変更できるように、参照によって配列要素を渡します。

foreach($array as &$itemnext):

一致するセットの最初の項目を 2 回取得する可能性があるため、これでも間違った回答が得られます。とにかくすべての値を元に戻すので、外側の要素にもフラグを設定するか、['aretirer'] をゼロに初期化することができます。

フラグ チェックを次のように置き換えることもできます。

  if(!isset($item['flag'])):

そうしないと、['flag'] が設定されていないと文句を言うでしょう (その警告が有効になっている場合)。

ただし、その解決策は、配列要素ごとに配列全体を 1 周します。これは、大きな配列の場合は遅くなります。より良いアイデアは、データをより優れた多次元配列に抽出することです。

foreach ($myArray as $data) { 
  if (!isset($newArray[$data['projet_id']][$data['activite_id']][$data['domaine_id']])) { 
    $newArray[$data['projet_id']][$data['activite_id']][$data['domaine_id']] = 0;
  };
  $newArray[$data['projet_id']][$data['activite_id']][$data['domaine_id']] += $data['aretirer'];  
}

データの扱いによっては、これで十分かもしれませんが、それ以外の場合は、そのデータを取得して元の配列形式を元に戻すことができます。

foreach($newArray as $projet_id => $act_domArray) { 
  foreach($act_domArray as $activite_id => $domArray) { 
    foreach($domArray as $domaine_id => $aretirer) { 
      $finalArray[] = array('projet_id' => $projet_id, 'activite_id' => $activite_id, 
                            'domaine_id' => $domaine_id, 'aretirer' => $aretirer);
    }
  }
}

または、データのオブジェクトを作成し、そのオブジェクトで比較メソッドを定義します。次に、それを使用して配列を折りたたみます。

于 2013-07-25T08:23:18.877 に答える
0

$array = array(  
    array(
        'projet_id' => '1',
        'activite_id' => '1',
        'domaine_id' => null,
        'aretirer' =>  4
    ),  
    array(
        'projet_id' => '1',
        'activite_id' => '3',
        'domaine_id' => null,
        'aretirer' =>  1
    ),  
    array(
        'projet_id' => '1',
        'activite_id' => '1',
        'domaine_id' => null,
        'aretirer' => 2
    ),  
    array(
        'projet_id' => '1',
        'activite_id' => '3',
        'domaine_id' => null,
        'aretirer' => 2
    )
);

$sortedArray = array();
$assignedValues = array();

foreach ($array as $arrayItem)
{
    $ukey = $arrayItem['projet_id'].'-'.$arrayItem['activite_id'].'-'.$arrayItem['domaine_id'];


    if (!isset($sortedArray[$ukey]))
    {
        $sortedArray[$ukey] = array();
    }

    $sortedArray[$ukey][] = $arrayItem['aretirer'];

    if (!isset($assignedValues[$ukey]))
    {
        $assignedValues[$ukey] = array(
            'projet_id' => $arrayItem['projet_id'],
            'activite_id' => $arrayItem['activite_id'],
            'domaine_id' => $arrayItem['domaine_id']
        );
    }
}

foreach ($sortedArray as $ukey => $arrayItem)
{
    $sum = array_sum($arrayItem);

    var_dump($assignedValues[$ukey]);
    var_dump('SUM: ' . $sum);
}

更新:セパレーターを追加

于 2013-07-25T08:24:20.433 に答える
0

このロジックを開発するのが私に任されているとしたら、このロジックを関数内に配置します。正直なところ、私はおそらくさらに一歩進んで、それをクラスに組み込むでしょう (特に、PHP >= 5.1 を使用している場合)。それはあなたが求めている範囲外ですが、オブジェクト指向プログラミングの実践に関する追加情報についてはhttp://php.net/manual/en/language.oop5.phpをチェックする価値があるかもしれません。

ただし、一意のインデックス (projet_id、activite_id、および domaine_id) に基づいて集計関数を実行する適切な foreach ステートメントに関する差し迫った質問を満たすために、以下を参照します。

$arrDataSetList = array(  
    0 => array(
        'projet_id' => '1',
        'activite_id' => '1',
        'domaine_id' => null,
        'aretirer' => (float) 4
    ),  
    1 => array(
            'projet_id' => '1',
            'activite_id' => '3',
            'domaine_id' => null,
            'aretirer' => (float) 1
        ),  
    2 => array(
            'projet_id' => '1',
            'activite_id' => '1',
            'domaine_id' => null,
            'aretirer' => (float) 2
        ),  
    3 => array(
            'projet_id' => '1',
            'activite_id' => '3',
            'domaine_id' => null,
            'aretirer' => (float) 2
        )
);

$arrAggregateDataSet = array();
$arrAggregateKeys = array('project_id','activite_id','domaine_id'); // Sets up the keys to define that to group your dataset with
foreach ($arrDataSetList as $arrDataSetListItem) {
    // STEP 1: Defining the aggregate key
    $arrKeyValues = array(); // Key values to join later
    foreach ($arrAggregateKeys as $strKey) {
        if (array_key_exists($strKey, $arrDataSetListItem) && !empty($arrDataSetListItem[$strKey]){
            $arrKeyValues[] = $arrDataSetListItem[$strKey];
        }
        else {
            $arrKeyValues[] = ''; // Empty if null
    }

    $strKey = join('-',$arrKeyValues);  // Your Unique Key for this Data Set List Item

    // STEP 2: If the unique key does not yet exist - initialize the aggregated dataset
    if (!array_key_exists($strKey, $arrAggregateDataSet)) {
        $arrAggregateDataSet[$strKey] = $arrDataSetListItem;
    }
    // STEP 3: If the unique key DOES exist, perform the aggregate functions necessary
    else {
        $arrAggregateDataSet[$strKey]['aretirer'] += $arrDataSetListItem['aretirer'];
    }
}

$arrAggregateDataSet で var_dump() 関数を使用すると、出力は次のようになります。

array(2) {
  ["1-1-"]=>
  array(4) {
    ["projet_id"]=>
    string(1) "1"
    ["activite_id"]=>
    string(1) "1"
    ["domaine_id"]=>
    NULL
    ["aretirer"]=>
    float(6)
  }
  ["1-3-"]=>
  array(4) {
    ["projet_id"]=>
    string(1) "1"
    ["activite_id"]=>
    string(1) "3"
    ["domaine_id"]=>
    NULL
    ["aretirer"]=>
    float(3)
  }
}

これは、PHP 4 (>= 4.0.7) および 5 のすべてのフレーバーで動作することが期待されています。

于 2013-07-25T08:35:17.393 に答える