There are two arrays of arrays. $user and $experience are two arrays and i want to achieve $final as my expected output.
I have two arrays:
$user = [
[
"country" => "aus",
"new_experiences" => 0,
"new_users" => 6
],
[
"country" => "jpn",
"new_experiences" => 0,
"new_users" => 5
]
];
$experience = [
[
"country" => "jpn",
"new_experiences" => 12,
"new_users" => 0
],
[
"country" => "usa",
"new_experiences" => 10,
"new_users" => 0
]
];
After merging these two arrays based on country, how can i get:
$final = [
[
"country" => "aus",
"new_experiences" => 0,
"new_users" => 6
],
[
"country" => "jpn",
"new_experiences" => 12,
"new_users" => 5
],
[
"country" => "usa",
"new_experiences" => 10,
"new_users" => 0
]
];
Try this
array_unique(array_merge($array1,$array2), SORT_REGULAR);
http://se2.php.net/manual/en/function.array-unique.php
You can achieve your GOal using this simple steps:
Iterate and arrange your array into a single array using foreach
Create a key-value array, just like I have created $issetArray
Push all the value in a $final array, you will get the desired output
I have created a simple logic using foreach loop, isset() and array_push()
$user = array(
array(
"country" => "aus",
"new_experiences" => 0,
"new_users" => 6
),
array(
"country" => "jpn",
"new_experiences" => 0,
"new_users" => 5
)
);
$experience = array(
array(
"country" => "jpn",
"new_experiences" => 12,
"new_users" => 0
),
array(
"country" => "usa",
"new_experiences" => 10,
"new_users" => 0
)
);
$final = array();
$issetArray = array();
foreach($user as $key => $value)
{
if(isset($issetArray[$value['country']]))
{
$issetArray[$value['country']]['new_experiences'] = $value;
$issetArray[$value['country']]['new_users'] = $value;
}
else
{
$issetArray[$value['country']] = $value;
}
}
foreach($experience as $key => $value)
{
if(isset($issetArray[$value['country']]))
{
$issetArray[$value['country']]['new_experiences'] = $value['new_experiences'];
$issetArray[$value['country']]['new_users'] = $value['new_users'];
}
else
{
$issetArray[$value['country']] = $value;
}
}
foreach($issetArray as $value)
{
array_push($final, $value);
}
echo "<pre>";
print_r($final);
Click on the link to know more about isset() and array_push()
Related
<?php
$userData = [
[
"UID" => "5f10482574d83d4b726fe5",
"name" => "Yug Gill",
"orgID" => "5f10481d74d83d4b726",
"imageURL" => "female.png"
]
];
$userProductsData = [
[
"UPID" => "5f10482574d83d4b6fe007",
"UID" => "5f10482574d83d4b726fe5",
]
];
$userDetailsResult = [];
foreach ($userData as $key => $value) {
$userData[$key]["UPID"] = $userProductsData[$value["UID"]] ?? [];
}
Expected Output
$userData = [
[
"UID" => "5f10482574d83d4b726fe5",
"name" => "Yug Gill",
"orgID" => "5f10481d74d83d4b726",
"imageURL" => "female.png",
"UPID" => "5f10482574d83d4b6fe007"
]
];
i have two aray UID common for both array, now i want to take UPID from $userProductsData and push into $userData, i have tried not working properly, kindly anyone update my code please
?>
Try this one.
$userData = [
[
"UID" => "5f10482574d83d4b726fe5",
"name" => "Yug Gill",
"orgID" => "5f10481d74d83d4b726",
"imageURL" => "female.png"
]
];
$userProductsData = [
[
"UPID" => "5f10482574d83d4b6fe007",
"UID" => "5f10482574d83d4b726fe5",
]
];
$userDetailsResult = [];
foreach ($userProductsData as $key => $value) {
$userData[$key]["UPID"] = $value['UPID'];
}
print_r($userData);
Your $userProductsData is a regular array, it has indexes 0, 1, 2 etc... Then you are trying to get an item from this array by string key "5f10482574d83d4b726fe5".
$userProductsData should be a key array like that:
$userProductsData = [
"5f10482574d83d4b726fe5" => [
"UPID" => "5f10482574d83d4b6fe007",
"UID" => "5f10482574d83d4b726fe5",
],
];
Then you can get an item from this array by key "5f10482574d83d4b726fe5".
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
I am currently able to sort a multidimensional array using a custom sorting method. Each array lineupSet has an n amount of items. The function sort_points will sort each lineupSet from highest to lowest totalPoints and then it will give me the lineupSet with the the highest total totalPoints. I am currently changing the approach, I still want to sort through each lineupSet first and order highest to lowest. Then I would like to get the highest totalPoints of each lineupSet based on a given count. What would be the best way to approach this?
Test Array:
$testArray = [[
"lineupSet" => [
[[
"formula" => [
"totalPoints" => 214.61,
],
"name" => "arr0-test0",
], [
"formula" => [
"totalPoints" => 201.17,
],
"name" => "arr0-test1",
]], [
"formula" => [
"totalPoints" => 5.01,
],
"name" => "arr0-test2",
]],
], [
"lineupSet" => [
[[
"formula" => [
"totalPoints" => 214.76,
],
"name" => "arr1-test0",
], [
"formula" => [
"totalPoints" => 220.66,
],
"name" => "arr1-test1",
]],
],
], [
"lineupSet" => [
[[
"formula" => [
"totalPoints" => 205.71,
],
"name" => "arr2-test0",
], [
"formula" => [
"totalPoints" => 204.43,
],
"name" => "arr2-test1",
]],
],
], [
"lineupSet" => [
[[
"formula" => [
"totalPoints" => 205.48,
],
"name" => "arr3-test0",
], [
"formula" => [
"totalPoints" => 203.51,
],
"name" => "arr3-test1",
]],
],
]];
Sorting Function
function sum_points($v) {
$totalPoints = 0;
foreach ($v['lineupSet'] as $lset) {
if (isset($lset['formula'])) {
$totalPoints += $lset['formula']['totalPoints'];
}
else {
foreach ($lset as $l) {
$totalPoints += $l['formula']['totalPoints'];
}
}
}
return $totalPoints;
}
function sort_points($a, $b) {
return sum_points($b) - sum_points($a);
}
usort($testArray, 'sort_points');
print_r($testArray[0]);
For example I want to get the top two highest 'totalPoints'. The desired outcome:
Array (
[lineupSet] => Array
(
[0] => Array
(
[0] => Array
(
[formula] => Array
(
[totalPoints] => 220.66
)
[name] => arr1-test1
)
[1] => Array
(
[formula] => Array
(
[totalPoints] => 214.76
)
[name] => arr0-test0
)
)
)
)
I want to do the same for the top n highest totalPoints. Keeping in mind that it will have to take at times n items from each lineupSet that are the highest totalPoints.
I think it's better to use an object then you can keep max while you are sorting data (also you can use a constructor to sort the array).
Class SortHelper{
public $max = 0;
private function checkMax($totalPoints){
if($totalPoints > $this->max)
$this->max = $totalPoints;
}
private function sum_points($v) {
$totalPoints = 0;
foreach ($v['lineupSet'] as $lset) {
if (isset($lset['formula'])) {
$totalPoints += $lset['formula']['totalPoints'];
$this->checkMax($lset['formula']['totalPoints']);
}
else {
foreach ($lset as $l) {
$totalPoints += $l['formula']['totalPoints'];
$this->checkMax($l['formula']['totalPoints']);
}
}
}
return $totalPoints;
}
private function sort_points($a, $b) {
return $this->sum_points($b) - $this->sum_points($a);
}
public function sort($array){
usort( $array, [$this, 'sort_points']);
return $array;
}
}
then you would have:
$sortHelper = new SortHelper();
$sorted_array = $sortHelper->sort($testArray);
var_dump($sorted_array[0]);
var_dump($sortHelper->max);
Check this out,
$n = 2; // number of elements
$testArray = [[
"lineupSet" => [
[[
"formula" => [
"totalPoints" => 214.61,
],
"name" => "arr0-test0",
], [
"formula" => [
"totalPoints" => 201.17,
],
"name" => "arr0-test1",
]], [
"formula" => [
"totalPoints" => 5.01,
],
"name" => "arr0-test2",
]
],
], [
"lineupSet" => [
[[
"formula" => [
"totalPoints" => 214.76,
],
"name" => "arr1-test0",
], [
"formula" => [
"totalPoints" => 220.66,
],
"name" => "arr1-test1",
]],
],
], [
"lineupSet" => [
[[
"formula" => [
"totalPoints" => 205.71,
],
"name" => "arr2-test0",
], [
"formula" => [
"totalPoints" => 204.43,
],
"name" => "arr2-test1",
]],
],
], [
"lineupSet" => [
[[
"formula" => [
"totalPoints" => 205.48,
],
"name" => "arr3-test0",
], [
"formula" => [
"totalPoints" => 203.51,
],
"name" => "arr3-test1",
]],
],
]];
function sort_points($a, $b)
{
return ($a['formula']['totalPoints'] > $b['formula']['totalPoints']) ? -1 : 1;
}
$result = [];
$reference = &$result['lineupSet'][0]; // store reference in $reference
foreach ($testArray as $tA) {
foreach ($tA['lineupSet'] as $t) {
foreach ($t as $child) {
$reference[] = $child;
}
}
}
usort($reference, 'sort_points');
$reference = array_slice($reference, 0, $n);
var_dump($result); // desired output
Please try this 2 functions, the steps as follows:
sort_points(); Sort it with arsort PHP function and return it to new simplified array.
transform_arrays($sortedArray, $testArray); $testArray will be changed the value by the sortedArray.
copy all the codes into single file of .php and run it.
*i assume that we don't care about the complexity, also in real life (in this case my life) there is nothing such the case that you need to sort in multidimensional array, because array is just the storage to keep the data can be read by human.
<?php
$testArray =
[
['lineupSet' => [[['formula' => ['totalPoints' => 214.61],'name' => 'arr0-test0'],['formula' => ['totalPoints' => 220.66],'name' => 'arr1-test1']]]],
['lineupSet' => [[['formula' => ['totalPoints' => 205.71],'name' => 'arr2-test0'],['formula' => ['totalPoints' => 204.43],'name' => 'arr2-test1']]]],
['lineupSet' => [[['formula' => ['totalPoints' => 205.48],'name' => 'arr3-test0'],['formula' => ['totalPoints' => 203.51],'name' => 'arr3-test1']]]]
];
// sort into another array
function sort_points($testArray = []){
$response = $result = [];
$i = 0;
foreach($testArray as $array2){
foreach($array2['lineupSet'][0] as $item){
$result[$item['name']] = $item['formula']['totalPoints'];
$i++;
}
}
arsort($result);
$i = 0;
foreach($result as $key => $val){
$response[$i]['name'] = $key;
$response[$i]['totalPoints'] = $val;
$i++;
}
return $response;
}
// this won't work if the $testArray format structure is changed
function transform_arrays($items, $testArray){
$l = 0;
for($i=0;$i<count($testArray);$i++){
for($j=0;$j<count($testArray[$i]);$j++){
for($k=0;$k<count($testArray[$i]['lineupSet'][$j]);$k++){
$testArray[$i]['lineupSet'][$j][$k]['formula']['totalPoints'] = $items[$l]['totalPoints'];
$testArray[$i]['lineupSet'][$j][$k]['name'] = $items[$l]['name'];
// print_r($testArray[$i]['lineupSet'][$j][$k]['formula']['totalPoints']);
// print_r($testArray[$i]['lineupSet'][$j][$k]);
$l++;
}
}
}
return $testArray;
}
echo '<pre>';
$sortedArray = sort_points($testArray);
$response = transform_arrays($sortedArray, $testArray);
print_r($response);
echo '</pre>';
I want to create dynamic menu with looping an array be 1 object menu. But error occured.
Our code is below it:
$menus = [{"id" => 1, "label" => "content", "parent_id" => 0},{"id" => 2, "label" => "inbox", "id" => 3, "parent_id" => 0}, {"id" => 4, "label" => "item", "parent_id" => 0}];
$sub_menus = [{"id" => 5, "label" => "banner", "parent_id" => 1},{"id" => 6, "label" => "ads", "parent_id" => 1}];
foreach($menus as $row => $value){
$nav[$row] = $value;
foreach($sub_menus as $r => $v) {
if($v['parent_id'] == $value['id']){
$nav[$row]['sub_menu'][$r] = $v;
}
}
}
I get error notif, "Indirect modification of overloaded element of App\Menu has no effect"
Please Help me :)
The code is working. You have a lot of bugs in your arrays.
Fixed:
$menus = [
[
"id" => 1,
"label" => "content",
"parent_id" => 0
],
[
"id" => 2,
"label" => "inbox",
"parent_id" => 0
],
[
"id" => 4,
"label" => "item",
"parent_id" => 0
]
];
$sub_menus = [
[
"id" => 5,
"label" => "banner",
"parent_id" => 1
],
[
"id" => 6,
"label" => "ads",
"parent_id" => 1
]
];
foreach($menus as $row => $value){
$nav[$row] = $value;
foreach($sub_menus as $r => $v) {
if($v['parent_id'] == $value['id']){
$nav[$row]['sub_menu'][$r] = $v;
}
}
}
You have a broken array, something like an incorrect conversion of json to an array;
You can test(execute) it here (working example)
I want to get only duplicated records in multidimentional array.
My array looks like:
"items": [
{
"id": "1",
"father_name": "YYY",
"surname": "XXX",
"name": "abc",
},
{
"id": "1",
"father_name": "YYY",
"surname": "XXX",
"name": "abc",
},
{
"id": "2",
"father_name": "ZZZ",
"surname": "UUU",
"name": "abc",
},
]
I want to get results like
"items": [
{
"id": "1",
"father_name": "YYY",
"surname": "XXX",
"name": "abc",
},
]
How can I get it? Please help me I am stuck here.
I have tried many things but everything works in single dimensional array
Thanks in advance!
As an alternative to other answers you could also do something like:
$duplicates = [];
while ($a = array_shift($array)) {
if (in_array($a, $array) && !in_array($a, $duplicates)) {
$duplicates[] = $a;
}
}
Hope this helps!
The given data is a json string.
Assuming the same for your array structure try this:
$arr = array("items"=>array(
"id"=> "1",
"father_name"=> "YYY",
"surname"=> "XXX",
"name"=> "abc",
),
array(
"id"=> "1",
"father_name"=> "YYY",
"surname"=> "XXX",
"name"=> "abc",
),
array(
"id"=> "2",
"father_name"=> "ZZZ",
"surname"=> "UUU",
"name"=> "abc",
)
);
$withoutDuplicates = array_unique($arr, SORT_REGULAR);
$duplicates = array_diff_assoc($arr, $withoutDuplicates);
echo "<pre>";
print_r($duplicates);
OUTPUT:
Array
(
[0] => Array
(
[id] => 1
[father_name] => YYY
[surname] => XXX
[name] => abc
))
<?php
$arr = array(
'items' => array(
0 => array(
'id' => '1',
'father_name' => 'YYY',
'surname' => 'XXX',
'name' => 'abc'
),
1 => array(
'id' => '1',
'father_name' => 'YYY',
'surname' => 'XXX',
'name' => 'abc'
),
2 => array(
'id' => '2',
'father_name' => 'ZZZ',
'surname' => 'UUU',
'name' => 'abc'
)
)
);
$result = array();
for ($i = 0; $i < count($arr['items'])-1; $i++) {
for ($x = $i+1; $x < count($arr['items']); $x++) {
if ($arr['items'][$i] !== $arr['items'][$x] || in_array($arr['items'][$i], $result))
continue;
array_push($result, $arr['items'][$i]);
}
}
print_r($result);
?>
One way to go at it, assuming you are working with multi-dimensional php arrays.
You can do something like this:
foreach($items as $key => $item)
{
unset($items[$key]);
if(array_search($item['id'], array_column($items, 'id_or_another_key')))
{
$result[] = $item;
}
}
The sense of this code is next:
You should go through the initial array in the cycle
Delete the current item from the array
Search the similar items by the 'id' value or by the another key between the rest elements
If the item was found, you put it to the result array with duplicated items.
<?php
/**
* #param $data array
*
* #return array
*/
function getDuplicatesOnly(array $data): array
{
$result = [
'items' => [
],
];
foreach ($data as $key => $datum) {
$itemId = $datum['id'];
unset($data[$key]);
$columns = array_column($data, 'id');
if(in_array($itemId, $columns)) {
$result['items'][] = $datum;
}
}
return $result;
}
$testData = [
'input' => [
'items' => [
[
'id' => '1',
'father_name' => 'YYY',
'surname' => 'XXX',
'name' => 'abc'
],
[
'id' => '1',
'father_name' => 'YYY',
'surname' => 'XXX',
'name' => 'abc'
],
[
'id' => '2',
'father_name' => 'ZZZ',
'surname' => 'UUU',
'name' => 'abc'
]
]
],
'output' => [
'items' => [
[
'id' => '1',
'father_name' => 'YYY',
'surname' => 'XXX',
'name' => 'abc'
]
],
],
];
$output = getDuplicatesOnly($testData['input']['items']);
assert($testData['output'] == $output, "Failed asserting data.");
Can be tested here.