PHP多维数组合并键并添加一个值

时间:2013-07-25 07:49:08

标签: php multidimensional-array sum

我的数组是这样的:

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

我想总结一下arejet_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;
}

谢谢你的帮助

3 个答案:

答案 0 :(得分: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):

这仍然会得到错误的答案,因为你可以在任何匹配集中的第一项两次。您也可以在外部元素上设置标记,或者只是将['aretirer']初始化为零,因为您无论如何都要重新添加所有值。

您还可以使用以下内容替换标记检查:

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

否则它会抱怨没有设置['flag'](如果你启用了警告)。

但是,对于每个数组元素,该解决方案会绕整个数组运行一次​​ - 对于大数组而言,这将会很慢。更好的想法是将数据提取到更好的多维数组中:

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);
    }
  }
}

或者,您为数据创建一个对象并在该对象中定义比较方法。然后使用它来折叠数组。

答案 1 :(得分: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);
}

更新:添加了分隔符

答案 2 :(得分: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。