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

如果由我来开发这个逻辑,我会把这个逻辑放在一个函数中。老实说,我可能会更进一步,将它构建到一个类中(特别是如果您使用的是 PHP >= 5.1)。尽管这超出了您要求的范围,但可能值得查看http://php.net/manual/en/language.oop5.php以获取有关面向对象编程实践的更多信息。

但是,为了满足您与正确的 foreach 语句相关的直接问题,该语句将基于唯一索引(projet_id、activite_id 和 domaine_id)执行聚合函数 - 我将参考以下内容:

$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 回答
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):

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

您还可以将标志检查替换为:

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

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

于 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 回答