0

I would appreciate some help regarding the processing of my below multidimensional array data. What I want to achieve is to build an array with duplicated dates as keys and the total amount in "nb" indexes for each duplicated date. This is what I've done so far:

<?php

$caOppo = [

     0 => [
    "nb" => "5000",
    "date" => "2016-01-26",
    "nb_enc" => "1",
    "tp" => "BUSINESS PB"
  ],
  1 =>[
    "nb" => "9100",
    "date" => "2016-01-26",
    "nb_enc" => "1",
    "tp" => "BLUE SOMETHING"
  ],
  2 => [
    "nb" => "12000",
    "date" => "2016-01-12",
    "nb_enc" => "1",
    "tp" => "BUSINESS MC"
  ],
  3 => [
    "nb" => "20000",
    "date" => "2016-01-22",
    "nb_enc" => "1",
    "tp" => "BUSINESS MC"
  ],
  4 => [
    "nb" => "29900",
    "date" => "2016-01-25",
    "nb_enc" => "1",
    "tp" => "KLIPAY"
  ],
  5 =>  [
    "nb" => "36350",
    "date" => "2016-01-04",
    "nb_enc" => "2",
    "tp" => "KLIPAY"
  ],
  6 =>  [
    "nb" => "36900",
    "date" => "2016-01-27",
    "nb_enc" => "1",
    "tp" => "BUSINESS PB"
  ],
  7 => [
    "nb" => "45400",
    "date" => "2016-01-13",
    "nb_enc" => "1",
    "tp" => "BUSINESS MC"
  ],
  8 => [
    "nb" => "50700",
    "date" => "2016-01-08",
    "nb_enc" => "3",
    "tp" => "BUSINESS MC"
  ],
  9 =>  [
    "nb" => "54000",
    "date" => "2016-01-07",
    "nb_enc" => "1",
    "tp" => "BLUE SOMETHING"
  ],
  10 =>  [
    "nb" => "61750",
    "date" => "2016-01-26",
    "nb_enc" => "3",
    "tp" => "BUSINESS MC"
  ],
  11 =>  [
    "nb" => "78900",
    "date" => "2016-01-15",
    "nb_enc" => "1",
    "tp" => "KLIPAY"
  ],
  12 =>  [
    "nb" => "171050",
    "date" => "2016-01-20",
    "nb_enc" => "8",
    "tpe_oppo" => "BUSINESS MC"
  ],
  13 =>  [
    "nb" => "172900",
    "date" => "2016-01-19",
    "nb_enc" => "7",
    "tp" => "BUSINESS MC"
  ],
  14 =>  [
    "nb" => "208950",
    "date" => "2016-01-22",
    "nb_enc" => "10",
    "tp" => "BUSINESS PB"
  ]     

];

$dates = [];
foreach ($caOppo as $uniqueCaOppo) {
    $dates[] = $uniqueCaOppo['date'];
}

//Retrieving duplicates
$duplicates = [];

foreach(array_count_values($dates) as $val => $c){
    if($c > 1){
        $duplicates[$val] = 0;      
    }
}


print_r($duplicates); // Returns Array ( [2016-01-26] => 0 [2016-01-22] => 0 ) 
//which is what is expected

For now the amount for each dupilicated is set to 0. Now we need to add up all the $caOppo[$i]['nb'] for each duplicated date, the result will replace 0.

for ($i=0; $i < count($caOppo); $i++) {
    if (in_array($caOppo[$i]['date'], array_keys($duplicates))) {
        foreach ($duplicates as $key => $value) {
            if($caOppo[$i]['date']= $key){
                $duplicates[$key] += $caOppo[$i]['nb'];         
            }
        }           
    }
}
print_r($duplicates); // Returns Array ( [2016-01-26] => 304800 [2016-01-22] 
//=> 304800 ), which is not what is expected

Thanks in advance for your help.

Also wondering if there is a way to transform all the multidimensional array so duplicated dates will be replaced by only one instance of that date containing the sum total in $caOppo[$i]['nb'].


   $cnt=count($caOppo);
for ($i=0;$i<$cnt;$i++) {
    $caOppo[$i]['nb']=(int)$caOppo[$i]['nb'];
    for ($j=0;$j<$i;$j++) {
        if (isset($caOppo[$j])&&($caOppo[$j]['date']===$caOppo[$i]
['date'])) {
            $caOppo[$j]['nb']+=$caOppo[$i]['nb'];
            $caOppo[$j]['tp']=[];
            $tp_value = $caOppo[$i]['tp'];
            $caOppo[$j]['tp'][$tp_value]=$caOppo[$i]['nb'];
            unset($caOppo[$i]);
            break;
        }
    }
}
Patrick
  • 129
  • 16
  • 1
    I'm not sure if it causes the problem, but the assignment in `if($caOppo[$i]['date']= $key)` looks wrong. You probably want == or === – jh1711 Jul 16 '17 at 20:34
  • @ jh1711 Thanks, that was the problem. Still I would like to have an answer regarding my last question – Patrick Jul 16 '17 at 21:36
  • Like this https://3v4l.org/J1sFJ ? – jh1711 Jul 16 '17 at 22:19
  • I forgot to mention that the script I linked only handles arrays with no 'holes' in their indexes. A call to array_values() might make sense before and/or after it – jh1711 Jul 16 '17 at 22:38
  • @jh1711 Just great!!! Many thanks for the link, you've made my day!!! – Patrick Jul 17 '17 at 07:56
  • @jh1711 If you don't mind, I would love to see from your approach in the link you provided how to replace the value of $caOppo[$i]['tp'] where the date is duplicated with an array containing all the values of $caOppo[$i]['tp']. For instance for 2016-01-26, it will be $caOppo[$i]['tp'] = ["BUSINESS PB"=>$var1, "BLUE SOMETHING"=>$var2, "BUSINESS MC"=>$var3]. I've just updated my initial post to show you what I have tried so far and doesn't work. – Patrick Jul 17 '17 at 11:42
  • there are a few small errors in your edit. `$caOppo[$i['nb'];` misses a ] and should throw a syntax error. `$caOppo[$i]['tpe_oppo'];` will never be set (since it isn't set in the original array, and $i will always be greater than $j). `$caOppo[$j]['tpe_oppo']=[];` is executed multiple times in the nested for loops. Each time you would loose any information saved before. Here is my approach for something close to your use case: https://3v4l.org/882MB. The main idea is: if there's no info start with an empty array. If the info isn't an array make it one. Then push any additional info321 – jh1711 Jul 17 '17 at 21:25
  • @jh1711 Thanks for your comments. Actually, it's $caOppo[$j]['tp'] which you can see in the array instead of $caOppo[$j]['tpe_oppo']. I've also just added the missing "]". I've seen the link, you didn't exactly what I expected! I'm very happy for your help! Many thanks! Now I'll try to change the type of $caOppo[$j]['tp'] in other elements of the array from string to array so the array is consistent. – Patrick Jul 18 '17 at 04:42
  • @jh1711 Actually, for instance, for the array element containing "2016-01-26", I expected this: `[0]=> array(4) { ["nb"]=> int(75850) ["date"]=> string(10) "2016-01-26" ["nb_enc"]=> string(1) "1" ["tp"]=> array(3) { ["BUSINESS PB"]=> int(5000) ["BLUE SOMETHING"]=> int(9100) ["BUSINESS MC"]=> int(61750) } }` – Patrick Jul 18 '17 at 07:35
  • @jh1711 There must be something wrong because when $caOppo data are retrieved directly from the database, the output is changing (sometimes duplicated dates are treated as non duplicated ones) depending on whether I use on my sql request "orderBy desc" or "order by asc" on "date" or on "nb". I still have lot of work with this. – Patrick Jul 18 '17 at 10:05
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/149463/discussion-between-patrick-bassoukissa-and-jh1711). – Patrick Jul 18 '17 at 10:05

0 Answers0