从其他2个数组构造一个关联数组,并通过公共键进行链接

Problem:

I would like to combine 2 associative arrays to make one. To link these arrays, the ID key is present in both.

Input:

To retrieve my contacts with api call, I have to do 2 requests : First to retrieve contacts with Id, and email adresse Second to get some informations like name, city etc.

The first one return an array like this :

$contactArray = array(
    array(
        "CreatedAt" => "2019-04-12T11:53:26Z",
        "DeliveredCount" => 0,
        "Email" => "terry@example.org",
        "ExclusionFromCampaignsUpdatedAt" => "2019-04-28T09:21:35Z",
        "ID" => 1864410583,
        "IsExcludedFromCampaigns" => false,
        "IsOptInPending" => false,
        "IsSpamComplaining" => false,
        "LastActivityAt" => "2019-04-28T09:21:35Z",
        "LastUpdateAt" => "2019-04-28T09:21:35Z",
        "Name" => "",
        "UnsubscribedAt" => "",
        "UnsubscribedBy" => ""
    ),
    array(
        "CreatedAt" => "2019-04-12T12:39:30Z",
        "DeliveredCount" => 0,
        "Email" => "duane@example.org",
        "ExclusionFromCampaignsUpdatedAt" => "",
        "ID" => 1864410588,
        "IsExcludedFromCampaigns" => false,
        "IsOptInPending" => false,
        "IsSpamComplaining" => false,
        "LastActivityAt" => "2019-04-12T12:39:30Z",
        "LastUpdateAt" => "2019-04-12T12:39:30Z",
        "Name" => "",
        "UnsubscribedAt" => "",
        "UnsubscribedBy" => ""
    )
);

The second call, return an array like

$contactDataArray =
        array(
            array(
                "ContactID" => 1864410583,
                "Data" => array(
                    array(
                        "Name" => "firstname",
                        "Value" => "Mark"
                    ),
                    array(
                        "Name" => "city",
                        "Value" => "Miami"
                    ),
                    array(
                        "Name" => "name",
                        "Value" => "Terry"
                    ),
                    array(
                        "Name" => "phone",
                        "Value" => "555-5555"
                    )
                ),
                "ID" => 1864410583
            ),
            array(
                "ContactID" => 1864410588,
                "Data" => array(
                    array(
                        "Name" => "firstname",
                        "Value" => "Jane"
                    ),
                    array(
                        "Name" => "city",
                        "Value" => "New York"
                    ),
                    array(
                        "Name" => "name",
                        "Value" => "Duane"
                    ),
                    array(
                        "Name" => "phone",
                        "Value" => "555-5555"
                    )
                ),
                "ID" => 1864410588
            )
        );

In $contactArray, the ID key matches with ContactID key and ID key in $contactDataArray

Attempt: I want an array formatted like this :

$output = array(
        array(
            "Email" => "terry@example.org",
            "ID" => 1864410583,
            "firstname" => "Mark",
            "city" => "Miami",
            "name" => "Terry",
            "phone" => "555-5555"
        ),
        array(
            "Email" => "duane@example.org",
            "ID" => 1864410588,
            "firstname" => "Jane",
            "city" => "New York",
            "name" => "Duane",
            "phone" => "555-5555"
        )
    );

I'm trying to achieve this with array_walk, but no succeed.

You can do this with foreach,

$result = [];
foreach ($contactDataArray as $key => $value) {
    $ids   = array_column($contactArray, "ID"); // fetching all values from contactArray
    if (!empty(array_intersect([$value['ContactID'], $value['ID']], $ids))) { // checking if both satisfy the condition
        $result[$key] = array_column($value['Data'], 'Value', 'Name'); // combining name and value
        // searchng for key with matched ContactID
        $result[$key]['Email'] = $contactArray[array_search($value["ContactID"], $ids)]['Email'];
        $result[$key]['ID'] = $value["ContactID"];
    }
}

Demo.

Can you please try with this?

$output = [];
for($i = 0; $i < count($contactDataArray); $i++) {
    $arrIDandEmail = [
        'Email' => isset($contactArray[$i]['Email']) ? $contactArray[$i]['Email'] : '', 
        'ID' => isset($contactDataArray[$i]['ID']) ? $contactDataArray[$i]['ID'] : ''
    ];
    $arrData = array_column($contactDataArray[$i]["Data"], "Value", "Name");
    $newArray = array_merge($arrIDandEmail, $arrData);
    $output[] = $newArray;
}

For PHP >= 7.1 you can use array destructuring using list()

<?php 

$output = [];

foreach ($contactDataArray as [
    'ID' => $id,
    'Data' => [
        ['Name' => $firstnameKey, 'Value' => $firstnameValue],
        ['Name' => $cityKey, 'Value' => $cityValue],
        ['Name' => $nameKey, 'Value' => $nameValue],
        ['Name' => $phoneKey, 'Value' => $phoneValue]
    ]
]) {
    $output[] = [
        "Email" => $contactArray[array_search($id, array_column($contactArray, 'ID'))]['Email'],
        "ID" => $id,
        $firstnameKey => $firstnameValue,
        $cityKey => $cityValue,
        $nameKey => $nameValue,
        $phoneKey => $phoneValue
    ];
}

var_dump($output);

Demo

You can use array_walk,array_combine,array_column for the desired array as a result

$res = [];
array_walk($contactArray, function($v, $k) use ($contactDataArray,&$res)
{
  $res[] = array_merge(['Email'=>$v['Email'],'ID'=>$v['ID']],
            array_combine(
                array_column($contactDataArray[$k]['Data'],'Name'),
                array_column($contactDataArray[$k]['Data'],'Value')
            )
   );
});
echo '<pre>';
print_r($res);

DEMO