PHP: How to merge two nested arrays by key - php

I have two arrays like:
$team = [
['id' => 1, 'name' => 'Team A'],
['id' => 2, 'name' => 'Team B'],
['id' => 3, 'name' => 'Team C'],
];
$people = [
['id' => 1, 'name' => 'Mark Hamill', 'team' => 1],
['id' => 2, 'name' => 'Nicolas Cage', 'team' => 2],
['id' => 3, 'name' => 'Tom Cruise', 'team' => 3],
['id' => 4, 'name' => 'Tom Hanks', 'team' => 1],
['id' => 5, 'name' => 'Brad Pitt', 'team' => 2],
['id' => 6, 'name' => 'Paul Smith', 'team' => 3],
['id' => 7, 'name' => 'Matt Daemon', 'team' => 1],
['id' => 8, 'name' => 'Robert Redford', 'team' => 2],
]
I would like to merge the $people array into the $team array as a child node based on the team id. So the result would be:
$team = [
[
'id' => 1,
'name' =>'Team A',
'members' => [
['id' => 1, 'name' => 'Mark Hamill', 'team' => 1],
['id' => 4, 'name' => 'Tom Hanks', 'team' => 1],
['id' => 7, 'name' => 'Matt Daemon', 'team' => 1],
]
],
[
'id' => 2,
'name' =>'Team B',
'members' => [
['id' => 2, 'name' => 'Nicolas Cage', 'team' => 2],
['id' => 5, 'name' => 'Brad Pitt', 'team' => 2],
['id' => 8, 'name' => 'Robert Redford', 'team' => 2],
]
],
[
'id' => 3,
'name' =>'Team C',
'members' => [
['id' => 3, 'name' => 'Tom Cruise', 'team' => 3],
['id' => 6, 'name' => 'Paul Smith', 'team' => 3],
]
],
];
I know I can loop through $team and add the relevant $people one at a time based on their 'team' id, but I was wondering if there was a more efficient way of doing this. In my project, either of the arrays could grow to contain up to around 50 items each and processing these one at a time is really slowing the page down.
Thanks

This will loop your $teams array and intersect with an array_column to get the arrays you want.
$teampeople = array_column($people, "team");
//Creates a lookup array of the teams from people array
foreach($team as &$t){
// Here I match from the lookup array and get the "main" arrays.
// Array_values remove the indexed from the resulting array to make it 0,1,2 etc.
$t['members'] = array_values(array_intersect_key($people, array_intersect($teampeople, [$t['id']])));
}
unset($t); // just to make sure you don't accidentally change the array
var_dump($team);
Outputs:
array(3) {
[0]=>
array(3) {
["id"]=>
int(1)
["name"]=>
string(6) "Team A"
["members"]=>
array(3) {
[0]=>
array(3) {
["id"]=>
int(1)
["name"]=>
string(11) "Mark Hamill"
["team"]=>
int(1)
}
[1]=>
array(3) {
["id"]=>
int(4)
["name"]=>
string(9) "Tom Hanks"
["team"]=>
int(1)
}
[2]=>
array(3) {
["id"]=>
int(7)
["name"]=>
string(11) "Matt Daemon"
["team"]=>
int(1)
}
}
}
[1]=>
array(3) {
["id"]=>
int(2)
["name"]=>
string(6) "Team B"
["members"]=>
array(3) {
[0]=>
array(3) {
["id"]=>
int(2)
["name"]=>
string(12) "Nicolas Cage"
["team"]=>
int(2)
}
[1]=>
array(3) {
["id"]=>
int(5)
["name"]=>
string(9) "Brad Pitt"
["team"]=>
int(2)
}
[2]=>
array(3) {
["id"]=>
int(8)
["name"]=>
string(14) "Robert Redford"
["team"]=>
int(2)
}
}
}
[2]=>
&array(3) {
["id"]=>
int(3)
["name"]=>
string(6) "Team C"
["members"]=>
array(2) {
[0]=>
array(3) {
["id"]=>
int(3)
["name"]=>
string(10) "Tom Cruise"
["team"]=>
int(3)
}
[1]=>
array(3) {
["id"]=>
int(6)
["name"]=>
string(10) "Paul Smith"
["team"]=>
int(3)
}
}
}
}
https://3v4l.org/kmvuR

try this:
foreach ($team as $t) {
$t['members'] = array_filter($people, function ($var) use ($t) {
return ($var['team'] == $t['id']);
})
}

Related

Sorting array of arrays using array_multisort() [Argument #1 is expected to be an array or a sort flag]

I have this array of arrays
foreach($qcatResults as $qcatResult){
...//codes to get stuff
$cats[] = array(
'category_code' => $qcatResult->category_code,
'category' => $qcatResult->category,
'item_count' => $item_count,
'max_qty' => (int)$max_qty
);
}
var_dump($cats);
which would result to something like
array(34) {
[0]=> array(4) { ["category_code"]=> string(2) "BB" ["category"]=> string(0) ""
["item_count"]=> string(1) "1" ["max_qty"]=> int(12000) }
[1]=> array(4) { ["category_code"]=> string(2) "AK" ["category"]=> string(6) "Anklet"
["item_count"]=> string(1) "1" ["max_qty"]=> int(6) }
[2]=> array(4) { ["category_code"]=> string(3) "BAC" ["category"]=> string(15) "Bag Accessories"
["item_count"]=> string(1) "2" ["max_qty"]=> int(352) }
[3]=> array(4) { ["category_code"]=> string(2) "WB" ["category"]=> string(4) "Bags"
["item_count"]=> string(1) "9" ["max_qty"]=> int(6290) }
[4]=> array(4) { ["category_code"]=> string(2) "AB" ["category"]=> string(20) "Bathroom Accessories"
["item_count"]=> string(2) "19" ["max_qty"]=> int(325) }
[5]=> array(4) { ["category_code"]=> string(2) "BK" ["category"]=> string(4) "Book"
["item_count"]=> string(2) "40" ["max_qty"]=>int(27291) }...
}
I want to sort $cats by max_qty in descending order, but array_multisort is giving out the error Message: array_multisort(): Argument #1 is expected to be an array or a sort flag
I have this usage of array_multisort():
var_dump(array_multisort($max_qty, SORT_DESC, $cats));
I think usort() can do the trick for you:
$cats=[
["category_code"=>"BB","category"=>"","item_count"=>"1","max_qty"=>12000],
["category_code"=>"AK","category"=>"Anklet","item_count"=>"1","max_qty"=>6],
["category_code"=>"BAC","category"=>"Bag Accessories","item_count"=>"2","max_qty"=>352],
["category_code"=>"WB","category"=>"Bags","item_count"=>"9","max_qty"=>6290],
["category_code"=>"AB","category"=>"Bathroom Accessories","item_count"=>"19","max_qty"=>325],
["category_code"=>"BK","category"=>"Book","item_count"=>"40","max_qty"=>27291]
];
usort($cats,function($a,$b){
return $b['max_qty']-$a['max_qty'];
});
var_export($cats);
Output:
array (
0 =>
array (
'category_code' => 'BK',
'category' => 'Book',
'item_count' => '40',
'max_qty' => 27291,
),
1 =>
array (
'category_code' => 'BB',
'category' => '',
'item_count' => '1',
'max_qty' => 12000,
),
2 =>
array (
'category_code' => 'WB',
'category' => 'Bags',
'item_count' => '9',
'max_qty' => 6290,
),
3 =>
array (
'category_code' => 'BAC',
'category' => 'Bag Accessories',
'item_count' => '2',
'max_qty' => 352,
),
4 =>
array (
'category_code' => 'AB',
'category' => 'Bathroom Accessories',
'item_count' => '19',
'max_qty' => 325,
),
5 =>
array (
'category_code' => 'AK',
'category' => 'Anklet',
'item_count' => '1',
'max_qty' => 6,
),
)

PHP array of Strings into int

I have an array with some string values
array(4) {
[0]=> array(2) { ["x"]=> string(13) "1475269218000" ["y"]=> string(1) "1" }
[1]=> array(2) { ["x"]=> string(13) "1475269222000" ["y"]=> string(1) "1" }
[2]=> array(2) { ["x"]=> string(13) "1475269231000" ["y"]=> string(1) "1" }
[3]=> array(2) { ["x"]=> string(13) "1475269241000" ["y"]=> string(1) "1" }
}
I need an output with only values as ints. So this would be the output.
[
[1475269218000,1],
[1475269222000,1],
[1475269231000,1]
[1475269241000,1]
]
Option 1:
$ar = [
['x' => '1475269218000', 'y' => '1'],
['x' => '1475269222000', 'y' => '1'],
['x' => '1475269231000', 'y' => '1'],
['x' => '1475269241000', 'y' => '1']
];
foreach($ar AS $key1 => $sub_ars) {
foreach($sub_ars AS $key2 => $val) {
$ar[$key1][$key2] = intval($val);
}
}
var_dump($ar);
Option 2:
$ar = [
['x' => '1475269218000', 'y' => '1'],
['x' => '1475269222000', 'y' => '1'],
['x' => '1475269231000', 'y' => '1'],
['x' => '1475269241000', 'y' => '1']
];
function intvalRecursive($val)
{
if(is_array($val)) {
return array_map('intvalRecursive', $val);
}
return intval($val);
}
$ar = array_map('intvalRecursive', $ar);
var_dump($ar);
Option 3 (stripping keys):
$ar = [
['x' => '1475269218000', 'y' => '1'],
['x' => '1475269222000', 'y' => '1'],
['x' => '1475269231000', 'y' => '1'],
['x' => '1475269241000', 'y' => '1']
];
foreach($ar AS $key => $val) {
$ar[$key] = array_values(array_map('intval', $val));
}
var_dump($ar);

Merging PHP arrays with different keys

I want to merge two arrays.
The first one looks like this:
array(28) {
[0]=>
array(17) {
["category_id"]=>
string(2) "11"
["image"]=>
string(27) "718426050751.jpg"
["parent_id"]=>
string(1) "1"
["top"]=>
string(1) "0"
["column"]=>
string(1) "1"
["sort_order"]=>
string(2) "21"
["status"]=>
string(1) "1"
["date_added"]=>
string(19) "2015-07-30 14:06:42"
["date_modified"]=>
string(19) "2016-01-05 12:21:32"
["language_id"]=>
string(1) "1"
["name"]=>
string(7) "Faucets"
["description"]=>
string(0) ""
["meta_description"]=>
string(0) ""
["meta_keyword"]=>
string(0) ""
["store_id"]=>
string(1) "1"
["product_count"]=>
string(1) "0"
["page_count"]=>
string(1) "0"
}
And the second one looks like this:
array(17) {
["category_id"]=>
string(2) "13"
["image"]=>
string(28) "4005176268779.jpg"
["parent_id"]=>
string(2) "11"
["top"]=>
string(1) "0"
["column"]=>
string(1) "1"
["sort_order"]=>
string(1) "2"
["status"]=>
string(1) "1"
["date_added"]=>
string(19) "2015-07-30 14:06:43"
["date_modified"]=>
string(19) "2016-01-07 14:10:53"
["language_id"]=>
string(1) "1"
["name"]=>
string(12) "Sink Faucets"
["description"]=>
string(0) ""
["meta_description"]=>
string(0) ""
["meta_keyword"]=>
string(0) ""
["store_id"]=>
string(1) "1"
["product_count"]=>
string(1) "0"
["page_count"]=>
string(1) "0"
}
As you can see the second one doesn't have a key like the first one does which is [0].
When I use:
$children = array_merge((array)$children, (array)$additional);
I get a merged array but the additional array is not getting a key which for me would preferably be [1] or +1 from the last array key.
Is it possible to do this?
Thanks
$array = [
"0" => ["key1"=>"val1", "key2"=>"val2"]
];
$merge = ["key1"=>"val3", "key2"=>"val4"];
array_merge($array, [$merge]);
result:
Array
(
[0] => Array
(
[key1] => val1
[key2] => val2
)
[1] => Array
(
[key1] => val3
[key2] => val4
)
)
http://sandbox.onlinephpfunctions.com/code/a2e7abb2d9580b5f487d56b99a782505633c840b
array_merge() is not necessary, you merely need to push the second array into the first. $a[]=$b; will add $b's data to $a and assign an auto-incremented key without a function call.
Code:
$a=[
0=>[
"category_id"=>"11",
"image"=>"718426050751.jpg",
"parent_id"=>"1",
"top"=>"0",
"column"=>"1",
"sort_order"=>"21",
"status"=>"1",
"date_added"=>"2015-07-30 14:06:42",
"date_modified"=>"2016-01-05 12:21:32",
"language_id"=>"1",
"name"=>"Faucets",
"description"=>"",
"meta_description"=>"",
"meta_keyword"=>"",
"store_id"=>"1",
"product_count"=>"0",
"page_count"=>"0"
]
];
$b=[
"category_id"=>"13",
"image"=>"4005176268779.jpg",
"parent_id"=>"11",
"top"=>"0",
"column"=>"1",
"sort_order"=>"2",
"status"=>"1",
"date_added"=>"2015-07-30 14:06:43",
"date_modified"=>"2016-01-07 14:10:53",
"language_id"=>"1",
"name"=>"Sink Faucets",
"description"=>"",
"meta_description"=>"",
"meta_keyword"=>"",
"store_id"=>"1",
"product_count"=>"0",
"page_count"=>"0"
];
$a[]=$b; // push, not merge
var_export($a);
Output:
array (
0 =>
array (
'category_id' => '11',
'image' => '718426050751.jpg',
'parent_id' => '1',
'top' => '0',
'column' => '1',
'sort_order' => '21',
'status' => '1',
'date_added' => '2015-07-30 14:06:42',
'date_modified' => '2016-01-05 12:21:32',
'language_id' => '1',
'name' => 'Faucets',
'description' => '',
'meta_description' => '',
'meta_keyword' => '',
'store_id' => '1',
'product_count' => '0',
'page_count' => '0',
),
1 =>
array (
'category_id' => '13',
'image' => '4005176268779.jpg',
'parent_id' => '11',
'top' => '0',
'column' => '1',
'sort_order' => '2',
'status' => '1',
'date_added' => '2015-07-30 14:06:43',
'date_modified' => '2016-01-07 14:10:53',
'language_id' => '1',
'name' => 'Sink Faucets',
'description' => '',
'meta_description' => '',
'meta_keyword' => '',
'store_id' => '1',
'product_count' => '0',
'page_count' => '0',
),
)

How to sort PHP array when there are multiple values

I have an array as below:
$people = array(
200 => array(
'id' => 12345,
'first_name' => 'Joe',
'surname' => 'Bloggs',
'age' => 23,
'sex' => 'm'
),
100 => array(
'id' => 12346,
'first_name' => 'Adam',
'surname' => 'Smith',
'age' => 18,
'sex' => 'm'
),
500 => array(
'id' => 12347,
'first_name' => 'Amy',
'surname' => 'Jones',
'age' => 21,
'sex' => 'f'
)
I want to sort this array on the first value that you can see as 200, 100 and 500.
$result = array(
array('name' => 'Tahir', 'age' => '40'),
array('name' => 'Usman', 'age' => '30'),
array('name' => 'Danish', 'age' => '20'),
array('name' => 'Aneeq', 'age' => '10')
);
echo '<pre>';
print_r($result);
echo '</pre>';
foreach ($result as $key => $row) {
$name[$key] = $row['name'];
$age[$key] = $row['age'];
}
array_multisort($age, SORT_ASC, $result);
echo '<pre>';
print_r($result);
echo '</pre>';
echo "<pre>";
echo "Name\t\tAge";
foreach ( $result as $var ) {
echo "\n", $var['name'], "\t\t", $var['age'];
}
You can use ksort() use ascending order and krsort() for descending order.
ksort($people);
krsort($people);
This should be as simple as:
ksort($people);
To make it sort by the actual numeric value (to make 1000 come after 500 not after 100), use:
ksort($people, SORT_NUMERIC);
ksort() sorts an array by its keys.
For example:
php > var_dump($people);
array(3) {
[200]=>
array(5) {
["id"]=>
int(12345)
["first_name"]=>
string(3) "Joe"
["surname"]=>
string(6) "Bloggs"
["age"]=>
int(23)
["sex"]=>
string(1) "m"
}
[100]=>
array(5) {
["id"]=>
int(12346)
["first_name"]=>
string(4) "Adam"
["surname"]=>
string(5) "Smith"
["age"]=>
int(18)
["sex"]=>
string(1) "m"
}
[500]=>
array(5) {
["id"]=>
int(12347)
["first_name"]=>
string(3) "Amy"
["surname"]=>
string(5) "Jones"
["age"]=>
int(21)
["sex"]=>
string(1) "f"
}
}
php > ksort($people);
php > var_dump($people);
array(3) {
[100]=>
array(5) {
["id"]=>
int(12346)
["first_name"]=>
string(4) "Adam"
["surname"]=>
string(5) "Smith"
["age"]=>
int(18)
["sex"]=>
string(1) "m"
}
[200]=>
array(5) {
["id"]=>
int(12345)
["first_name"]=>
string(3) "Joe"
["surname"]=>
string(6) "Bloggs"
["age"]=>
int(23)
["sex"]=>
string(1) "m"
}
[500]=>
array(5) {
["id"]=>
int(12347)
["first_name"]=>
string(3) "Amy"
["surname"]=>
string(5) "Jones"
["age"]=>
int(21)
["sex"]=>
string(1) "f"
}
}
php >
You can try this solution.
<?php
$people = array(
200 => array(
'id' => 12345,
'first_name' => 'Joe',
'surname' => 'Bloggs',
'age' => 23,
'sex' => 'm'
),
100 => array(
'id' => 12346,
'first_name' => 'Adam',
'surname' => 'Smith',
'age' => 18,
'sex' => 'm'
),
500 => array(
'id' => 12347,
'first_name' => 'Amy',
'surname' => 'Jones',
'age' => 21,
'sex' => 'f'
));
ksort($people, SORT_NUMERIC);
print_r($people);
?>
You can use the following two functions according to your requirement:-
ksort() - sort associative arrays in ascending order, according to the key
krsort() - sort associative arrays in descending order, according to the key
How you can use it:-
ksort($people);
krsort($people);

PHP Sorting multidimesional array by first key

i got an array like this:
array
'list_10' =>
array
row_0 =>
array
'Id' => string '118579'
'Status' => string '3'
row_1 =>
array
'Id' => string '117662'
'Status' => string '2'
row_2 =>
array
'Id' => string '117662'
'Status' => string '2'
'list_11' =>
array
row_0 =>
array
'Id' => string '112564'
'Status' => string '2'
row_1 =>
array
'Id' => string '153622'
'Status' => string '3'
row_2 =>
array
'Id' => string '112832'
'Status' => string '1'
i want to "natsort" the first key "list_XX", making it start with 0,1,2,.. instead of 10,11,12,13,0,1,2,3,...
i played around with array_multisort but i cant seem to
set the right params to make it do what i want, if its even capable of doing this.
any advice?
Assuming your array is something like this:
$array = [
'list_11' =>
[
'row_0' =>
[
'Id' => '118579',
'Status' => '3'
],
'row_1' =>
[
'Id' => '117662',
'Status' => '2'
],
'row_2' =>
[
'Id' => '117662',
'Status' => '2'
]
],
'list_10' =>
[
'row_0' =>
[
'Id' => '112564',
'Status' => '2'
],
'row_1' =>
[
'Id' => '153622',
'Status' => '3'
],
'row_2' =>
[
'Id' => '112832',
'Status' => '1'
]
],
'list_1' =>
[
'row_0' =>
[
'Id' => '32323232',
'Status' => '3'
],
'row_1' =>
[
'Id' => '2353333',
'Status' => '2'
],
'row_2' =>
[
'Id' => '117662',
'Status' => '2'
]
]
];
Using array_multisort :
$sort = [];
foreach($array as $el=>$val){
$sort[] = $el;
}
array_multisort($array,SORT_NUMERIC,$sort,SORT_NATURAL);
var_dump($array);
Will print :
array(3) {
["list_1"]=>
array(3) {
["row_0"]=>
array(2) {
["Id"]=>
string(8) "32323232"
["Status"]=>
string(1) "3"
}
["row_1"]=>
array(2) {
["Id"]=>
string(7) "2353333"
["Status"]=>
string(1) "2"
}
["row_2"]=>
array(2) {
["Id"]=>
string(6) "117662"
["Status"]=>
string(1) "2"
}
}
["list_10"]=>
array(3) {
["row_0"]=>
array(2) {
["Id"]=>
string(6) "112564"
["Status"]=>
string(1) "2"
}
["row_1"]=>
array(2) {
["Id"]=>
string(6) "153622"
["Status"]=>
string(1) "3"
}
["row_2"]=>
array(2) {
["Id"]=>
string(6) "112832"
["Status"]=>
string(1) "1"
}
}
["list_11"]=>
array(3) {
["row_0"]=>
array(2) {
["Id"]=>
string(6) "118579"
["Status"]=>
string(1) "3"
}
["row_1"]=>
array(2) {
["Id"]=>
string(6) "117662"
["Status"]=>
string(1) "2"
}
["row_2"]=>
array(2) {
["Id"]=>
string(6) "117662"
["Status"]=>
string(1) "2"
}
}
}

Categories