Search code examples
phparraysjsonarray-merge

combine identical values in php arrays


I have a hard one to crack.

I have this array with emails:

Array ( 
[0] => [email protected] 
[1] => [email protected] 
[2] => [email protected] 
[3] => [email protected] 
[4] => [email protected] 
[5] => [email protected] 
[6] => [email protected] 
)

And this array with form ids:

Array ( 
[0] => 1a21f6b7-8025-4724-b983-14745823ede1 
[1] => 4c8a63c0-4650-4884-b83c-70054f538ec2 
[2] => 148c1886-6674-45f3-9665-748bb6a34f4c 
[3] => 02fc3795-9457-4b02-91da-7d4b63eac1c0 
)

And with this foreach I am running through every mail in the array to create a full JSON object

foreach($mails_array as $key => $value) {

    foreach($formIds as $form) {

         $branchArray = array(
                   "FormIds" => [''.$form.''],
                   "Conditions" => array("sendto" => $value),
                   "From" => $date_from,
                   "To" => $date_to,
                   "Days" => ''
               );

         array_push($array, $branchArray);
    }  
}

$json = json_encode($array);
$string = preg_replace('/"([^"]+)"\s*:\s*/', '$1:', $json);

This creates this json that is used to call an API to return number of submissions on X forms based on a condition (sendto):

[{FormIds:["1a21f6b7-8025-4724-b983-14745823ede1"],Conditions:{sendto:"[email protected]"},From:"2016-03-23",To:"today",Days:""},{FormIds:["4c8a63c0-4650-4884-b83c-70054f538ec2"],Conditions:{sendto:"[email protected]"},From:"2016-03-23",To:"today",Days:""},{FormIds:["148c1886-6674-45f3-9665-748bb6a34f4c"],Conditions:{sendto:"[email protected]"},From:"2016-03-23",To:"today",Days:""},{FormIds:["02fc3795-9457-4b02-91da-7d4b63eac1c0"],Conditions:{sendto:"[email protected]"},From:"2016-03-23",To:"today",Days:""},{FormIds:["1a21f6b7-8025-4724-b983-14745823ede1"],Conditions:{sendto:"[email protected]"},From:"2016-03-23",To:"today",Days:""},{FormIds:["4c8a63c0-4650-4884-b83c-70054f538ec2"],Conditions:{sendto:"[email protected]"},From:"2016-03-23",To:"today",Days:""},{FormIds:["148c1886-6674-45f3-9665-748bb6a34f4c"],Conditions:{sendto:"[email protected]"},From:"2016-03-23",To:"today",Days:""},{FormIds:["02fc3795-9457-4b02-91da-7d4b63eac1c0"],Conditions:{sendto:"[email protected]"},From:"2016-03-23",To:"today",Days:""},{FormIds:["1a21f6b7-8025-4724-b983-14745823ede1"],Conditions:{sendto:"[email protected]"},From:"2016-03-23",To:"today",Days:""},{FormIds:["4c8a63c0-4650-4884-b83c-70054f538ec2"],Conditions:{sendto:"[email protected]"},From:"2016-03-23",To:"today",Days:""},{FormIds:["148c1886-6674-45f3-9665-748bb6a34f4c"],Conditions:{sendto:"[email protected]"},From:"2016-03-23",To:"today",Days:""},{FormIds:["02fc3795-9457-4b02-91da-7d4b63eac1c0"],Conditions:{sendto:"[email protected]"},From:"2016-03-23",To:"today",Days:""},{FormIds:["1a21f6b7-8025-4724-b983-14745823ede1"],Conditions:{sendto:"[email protected]"},From:"2016-03-23",To:"today",Days:""},{FormIds:["4c8a63c0-4650-4884-b83c-70054f538ec2"],Conditions:{sendto:"[email protected]"},From:"2016-03-23",To:"today",Days:""},{FormIds:["148c1886-6674-45f3-9665-748bb6a34f4c"],Conditions:{sendto:"[email protected]"},From:"2016-03-23",To:"today",Days:""},{FormIds:["02fc3795-9457-4b02-91da-7d4b63eac1c0"],Conditions:{sendto:"[email protected]"},From:"2016-03-23",To:"today",Days:""},{FormIds:["1a21f6b7-8025-4724-b983-14745823ede1"],Conditions:{sendto:"[email protected]"},From:"2016-03-23",To:"today",Days:""},{FormIds:["4c8a63c0-4650-4884-b83c-70054f538ec2"],Conditions:{sendto:"[email protected]"},From:"2016-03-23",To:"today",Days:""},{FormIds:["148c1886-6674-45f3-9665-748bb6a34f4c"],Conditions:{sendto:"[email protected]"},From:"2016-03-23",To:"today",Days:""},{FormIds:["02fc3795-9457-4b02-91da-7d4b63eac1c0"],Conditions:{sendto:"[email protected]"},From:"2016-03-23",To:"today",Days:""},{FormIds:["1a21f6b7-8025-4724-b983-14745823ede1"],Conditions:{sendto:"[email protected]"},From:"2016-03-23",To:"today",Days:""},{FormIds:["4c8a63c0-4650-4884-b83c-70054f538ec2"],Conditions:{sendto:"[email protected]"},From:"2016-03-23",To:"today",Days:""},{FormIds:["148c1886-6674-45f3-9665-748bb6a34f4c"],Conditions:{sendto:"[email protected]"},From:"2016-03-23",To:"today",Days:""},{FormIds:["02fc3795-9457-4b02-91da-7d4b63eac1c0"],Conditions:{sendto:"[email protected]"},From:"2016-03-23",To:"today",Days:""},{FormIds:["1a21f6b7-8025-4724-b983-14745823ede1"],Conditions:{sendto:"[email protected]"},From:"2016-03-23",To:"today",Days:""},{FormIds:["4c8a63c0-4650-4884-b83c-70054f538ec2"],Conditions:{sendto:"[email protected]"},From:"2016-03-23",To:"today",Days:""},{FormIds:["148c1886-6674-45f3-9665-748bb6a34f4c"],Conditions:{sendto:"[email protected]"},From:"2016-03-23",To:"today",Days:""},{FormIds:["02fc3795-9457-4b02-91da-7d4b63eac1c0"],Conditions:{sendto:"[email protected]"},From:"2016-03-23",To:"today",Days:""}]

Where FormIds is a GUID of a particular form with submission. "sendto" in conditions is the mail that I want all submissions for on the particular form.

So as an example I am trying to get all submission on all 4 forms that are send to [email protected]

The above json returns this, where the number is submissions on the condition:

{
  "arr": [
    1,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    1,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0
  ]
}

So that I know that the first 4 items ( 4 form ids ) in the returned JSON is for [email protected] (1,0,0,0), the next 4 for [email protected] (0,0,0,0), e.t.c.

Now my problem is that I want to combine the mail array and the returned json into a simple json that I can output with the email address and the number of total submissions. The 4 forms with identical "sendto" should be combined, so that the condition with [email protected] that are found on 4 forms, will be combined into a single item with the total number of submissions on the 4 forms.

Something like:

{"landingPageData":[{"landingPage":{"landingPageMail":"[email protected]","landingPageLeads":"1"}},{"landingPage":{"landingPageMail":"[email protected]","landingPageLeads":0}},{"landingPage":{"landingPageMail":"[email protected]","landingPageLeads":"1"}},{"landingPage":{"landingPageMail":"[email protected]","landingPageLeads":"0"}},{"landingPage":{"landingPageMail":"[email protected]","landingPageLeads":"0"}},{"landingPage":{"landingPageMail":"[email protected]","landingPageLeads":"-"}},{"landingPage":{"landingPageMail":"[email protected]","landingPageLeads":"0"}}],"totalLeads":2})


Solution

  • You can iterate through $mails_array and sum subtotals using array_sum( array_slice() ):

    $json = '{"arr":[1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}';
    
    $data = json_decode( $json )->arr;
    $result = array( 'landingPageData'=>[], 'totalLeads'=>0 );
    
    foreach( $mails_array as $key => $email )
    {
        $subTot = array_sum( array_slice( $data,$key*count( $formIds ), count( $formIds ) ) );
        $result['landingPageData'][] = array
        (
            'landingPage' => array
            (
                'landingPageMail'  => $email,
                'landingPageLeads' => $subTot
            )
    
        );
        $result['totalLeads'] += $subTot;
    }
    
    $result = json_encode( $result );
    
    echo $result;
    

    will print (prettified):

    {
        "landingPageData": [
            {
                "landingPage": {
                    "landingPageMail": "[email protected] ",
                    "landingPageLeads": 1
                }
            },
            {
                "landingPage": {
                    "landingPageMail": "[email protected] ",
                    "landingPageLeads": 0
                }
            },
            {
                "landingPage": {
                    "landingPageMail": "[email protected] ",
                    "landingPageLeads": 1
                }
            },
            {
                "landingPage": {
                    "landingPageMail": "[email protected] ",
                    "landingPageLeads": 0
                }
            },
            {
                "landingPage": {
                    "landingPageMail": "[email protected] ",
                    "landingPageLeads": 0
                }
            },
            {
                "landingPage": {
                    "landingPageMail": "[email protected] ",
                    "landingPageLeads": 0
                }
            },
            {
                "landingPage": {
                    "landingPageMail": "[email protected] ",
                    "landingPageLeads": 0
                }
            }
        ],
        "totalLeads": 2
    }
    

    This is the core line:

    $subTot = array_sum( array_slice( $data, $key*count( $formIds ), count( $formIds ) ) );
    

    Multiplying current mails_array key for $formIds we can obtain starting $data key for current element, then we can extract from $data only values related with current email and sum them using array_sum(). The sum is added to a new landingPageData child and the totalLeads value is incremented by it.