I have an array of objects for example:
Array
(
[0] => Array
(
[Id] => 1
[Name] => Toy Car
[Category] => Toys
[Price] => 2.99
[OnSale] => false
)
...
)
But I'd like them to be grouped by Category, then by OnSale.
So far I have been able to group by category using:
$result = array();
foreach ($data as $element) {
$result[$element['Category']][] = $element;
}
But I am unsure how to nest another foreach or recursively group them once they have been grouped by Category. Any help is appreciated!
Do you mean:
$result = array();
foreach ($data as $element) {
$result[$element['Category']][$element['OnSale']][] = $element;
}
EDIT: Sorry, bit of a problem with all the [ and ]...
You're close! You just need to add the second key you want to group by.
$byCategoryAndSale = [];
foreach ($inventory as $item) {
$byCategoryAndSale[$item['Category']][$item['OnSale']][] = $item;
}
Note Using a boolean value as an array key will equate to 1's and 0's which can get pretty confusing.
Here's a full example:
<?php
$inventory = [
[
'Id' => 1,
'Name' => 'Toy Car',
'Category' => 'Toys',
'Price' => 2.99,
'OnSale' => false
],
[
'Id' => 2,
'Name' => 'Another Toy',
'Category' => 'Toys',
'Price' => 1.99,
'OnSale' => false
],
[
'Id' => 3,
'Name' => 'Hamburger',
'Category' => 'Not Toys',
'Price' => 5.99,
'OnSale' => false
],
[
'Id' => 4,
'Name' => 'Last Toy',
'Category' => 'Toys',
'Price' => 50.99,
'OnSale' => true
]
];
$byCategoryAndSale = [];
foreach ($inventory as $item) {
$byCategoryAndSale[$item['Category']][$item['OnSale']][] = $item;
}
print_r($byCategoryAndSale);
?>
Which yields:
PS C:\> php test.php
(
[Toys] => Array
(
[0] => Array
(
[0] => Array
(
[Id] => 1
[Name] => Toy Car
[Category] => Toys
[Price] => 2.99
[OnSale] =>
)
[1] => Array
(
[Id] => 2
[Name] => Another Toy
[Category] => Toys
[Price] => 1.99
[OnSale] =>
)
)
[1] => Array
(
[0] => Array
(
[Id] => 4
[Name] => Last Toy
[Category] => Toys
[Price] => 50.99
[OnSale] => 1
)
)
)
[Not Toys] => Array
(
[0] => Array
(
[0] => Array
(
[Id] => 3
[Name] => Hamburger
[Category] => Not Toys
[Price] => 5.99
[OnSale] =>
)
)
)
)
Related
My array is like this,
$options = Array
(
[0] => Array
(
[value] => 180
[label] => Nokia
)
[1] => Array
(
[value] => 2341
[label] => Suisses
)
[2] => Array
(
[value] => 143
[label] => Nokia
)
[3] => Array
(
[value] => 2389
[label] => 3D Pop Art
)
)
and i want output as,
Array(
[0] => Array
(
[value] => 180
[label] => Nokia
)
[2] => Array
(
[value] => 143
[label] => Nokia
)
)
Can anyone suggest me in this.
You can try something like this:
$options = [
0 => [
'value' => 180,
'label' => 'Nokia'
],
1 => [
'value' => 2341,
'label' => 'Suisses'
],
2 => [
'value' => 143,
'label' => 'Nokia'
],
3 => [
'value' => 2389,
'label' => '3D Pop Art'
],
];
$labels = [];
$duplicates = [];
foreach ($options as $option) {
if (!empty($duplicates[$option['label']])) {
$duplicates[$option['label']][] = $option;
}
if (empty($labels[$option['label']])) {
$labels[$option['label']] = $option;
} else {
$duplicates[$option['label']] = [
$labels[$option['label']],
$option
];
}
}
It seems you are looking for group by 'label'
foreach($options as $v){
$c[$v['label']][] = $v['value'];
}
print_r($c);
Working example : https://3v4l.org/62dv0
The array_filter() function is what you are looking for:
<?php
$data = [
[
'value' => 180,
'label' => "Nokia"
],
[
'value' => 2341,
'label' => "Suisses"
],
[
'value' => 143,
'label' => "Nokia"
],
[
'value' => 2389,
'label' => "3D Pop Art"
]
];
$output = [];
array_walk($input, function($entry) use (&$output) {
$output[$entry['label']][] = $entry;
});
print_r(
array_filter(
$output,
function($entry) {
return count($entry) > 1;
}
)
);
The output obviously is:
Array
(
[Nokia] => Array
(
[0] => Array
(
[value] => 180
[label] => Nokia
)
[1] => Array
(
[value] => 143
[label] => Nokia
)
)
)
That output slightly differs from the one suggested by you. But it has the advantage that you can tell entries apart by the doubled label.
Currently, I have 2 multidimensional array and I'm looking to combine them into one giant array where the value's name in array 1 matches the value's name in array 2.
The array's look as followed...
Array1
(
[0] => Array
(
[id] => 1
[name] => test1
[desc] => test_desc
[quantity] => 3
)
[1] => Array
(
[id] => 2
[name] => test2
[desc] => test_desc
[quantity] => 33
)
)
Array2
(
[0] => Array
(
[holder] => 'John'
[name] => test1
[desc] => test_desc
[location] => ATL
)
[1] => Array
(
[holder] => 'Jackie'
[name] => test3
[desc] => test_desc
[location] => SF
)
)
I'm looking to merge the arrays where the 'name' column in array1 matches in array2 and also combine the columns in array's 1 & 2 into the final array. This should look like...
FinalArray
(
[0] => Array
(
[id] => 1
[holder] => 'John'
[name] => test1
[desc] => test_desc
[location] => ATL
[quantity] => 3
)
[1] => Array
(
[holder] => 'Jackie'
[name] => test3
[desc] => test_desc
[location] => SF
)
[2] => Array
(
[id] => 2
[name] => test2
[desc] => test_desc
[quantity] => 33
)
)
Where the "test1" combines the different columns across the 2 arrays into a new array inside the "FinalArray". I've tried researching some ideas with array_merge and array_merge_recursive but I'm not entirely sure if I'm going in the correct direction. Thanks in advance.
Try like this
$array1=[['id' => 1,'name' => 'test1','desc' => 'test_desc','quantity' => 3],
['id' => 2,'name' => 'test2','desc' => 'test_desc','quantity' => 33]];
$array2=[['holder' => 'John','name' => 'test1','desc' => 'test_desc','location' => 'ATL'],
['holder' => 'Jackie','name' => 'test3','desc' => 'test_desc','location' => 'SF']];
$final=[];
foreach ($array1 as $key1=>$data1){
foreach ($array2 as $key2=>$data2){
if($data1['name']==$data2['name']){
$final[]=$data1+$data2;
unset($array1[$key1]);
unset($array2[$key2]);
}
}
}
if(!empty($array1)){
foreach ($array1 as $value){
$final[]=$value;
}
}
if(!empty($array2)){
foreach ($array2 as $value){
$final[]=$value;
}
}
It will give output as
One more solution
function merge_by_name(array $arr1, array $arr2) {
$result = [];
foreach ($arr1 as $value) {
$key = array_search($value['name'], array_column($arr2, 'name'));
if($key !== false) {
$result[] = array_merge($value, $arr2[$key]);
unset($arr2[$key]);
} else {
$result[] = $value;
}
}
$result = array_merge($result, $arr2);
return $result;
}
Test
$arr1 = [
[
'id' => 1,
'name' => 'test1',
'desc' => 'test_desc',
'quantity' => 3
],
[
'id' => 2,
'name' => 'test2',
'desc' => 'test_desc',
'quantity' => 33
],
];
$arr2 = [
[
'holder' => 'John',
'name' => 'test1',
'desc' => 'test_desc',
'location' => 'ATL'
],
[
'holder' => 'Jackie',
'name' => 'test3',
'desc' => 'test_desc',
'location' => 'SF'
],
];
var_export(merge_by_name($arr1, $arr2));
Result
array (
0 =>
array (
'id' => 1,
'name' => 'test1',
'desc' => 'test_desc',
'quantity' => 3,
'holder' => 'John',
'location' => 'ATL',
),
1 =>
array (
'id' => 2,
'name' => 'test2',
'desc' => 'test_desc',
'quantity' => 33,
),
2 =>
array (
'holder' => 'Jackie',
'name' => 'test3',
'desc' => 'test_desc',
'location' => 'SF',
),
)
I have below array,
Array ( [0] => Array ( [location] => X33 [usernumber] => 1 [order] => XX [part_number] => Hi ) [1] => Array ( [location] => X33 [usernumber] => 1 [order] => XX [part_number] => 68730 ) [2] => Array ( [location] => W33 [usernumber] => 2 [order] => YY [part_number] => 68741) [3] => Array ( [location] => W33 [usernumber] => 2 [order] => YY [part_number] => Hello )
I want to filter this array with usernumber = 1, by this it will create 1 array with arrays which have usernumber = 1, similarly it will create for usernumber=2
I had users in DB and will search user in this array,
I tried below code,
$users = $this->admin_model->get_usersforshipment();
foreach ($users as $user) {
$filtered = array_filter($csv_array, function($user)
{ //Below is retrurning as orignal $csv_array, not filtered,
return !empty($user['usernumber']);
});
}
Desired output, when $users['usernumber] == 1
Array ( [0] => Array ( [location] => X33 [usernumber] => 1 [order] => XX [part_number] => Hi ) [1] => Array ( [location] => X33 [usernumber] => 1 [order] => XX [part_number] => 68730 ) )
Desired output, when $users['usernumber] == 2
Array ( [0] => Array ( [location] => W33 [usernumber] => 2 [order] => YY [part_number] => 68741) [1] => Array ( [location] => W33 [usernumber] => 2 [order] => YY [part_number] => Hello )
How can i filter only 2 arrays from Multi Dimension array?
Online Example, Description added after your feedback.
$arr = array(
array ('location' => 'X33',
'usernumber' => 1,
'order' => 'XX',
'part_number' => 'Hi'
),
array ('location' => 'X33',
'usernumber' => 1,
'order' => 'XX',
'part_number' => '68730'
),
array ('location' => 'W33',
'usernumber' => 2,
'order' => 'YY',
'part_number' => '68741'
),
array ('location' => 'W33',
'usernumber' => 2,
'order' => 'YY',
'part_number' => 'Hello'
)
);
$out = array();
$index = $arr[0]['usernumber'];
foreach($arr as $val){
if($index != $val['usernumber'])
$index = $val['usernumber'];
$out[$index][] = $val;
}
echo '<pre>';
print_r($out);
Currently, your array is defined like so:
$array = [
0 => [
'location' => l1
'usernumber' => 1
'order' => 'o1'
],
1 => [
'location' => l2
'usernumber' => 1
'order' => 'o2'
],
2 => [
'location' => l3
'usernumber' => 2
'order' => 'o3'
]
];
A good solution would be to set the usernumber variables as array keys. You could do this while creating the array, or you could alter it after creation. It should look like this:
$array = [
1 => [ // The key is now the usernumber
[
'location' => 'l1'
'order' => 'o1'
],
[
'location' => 'l2'
'order' => 'o2'
]
],
2 => [
[
'location' => 'l3'
'order' => 'o3'
],
]
];
Now you can simple grab the different orders by the usernumber and loop through them:
$orders = $array[1]; // Get all orders from the user with usernumber 1
foreach ($orders as $order) {
print_r($order);
}
I'm losing my hair on this one... I have an array structure that print_r's like this (I've hidden unnecessary fields):
[0] => Array
(
[id] => 14
[name] => Foo Directory
)
[1] => Array
(
[id] => 16
[name] => Bar Project
[parent] => Array
(
[id] => 14
[name] => Foo Directory
)
)
[2] => Array
(
[id] => 20
[name] => Baz Project
[parent] => Array
(
[id] => 16
[name] => Bar Project
)
)
[3] => Array
(
[id] => 10
[name] => Qux Project
[parent] => Array
(
[id] => 16
[name] => Bar Project
)
And I need it to be nested like this:
[0] => Array
(
[id] => 14
[name] => Foo Directory
[children] => Array
(
[id] => 16
[name] => Bar Project
[children] => Array
(
[id] => 20
[name] => Baz Project
)
(
[id] => 10
[name] => Qux Project
)
)
)
What I've tried so far
$projTree = array();
foreach ($projects as $project) {
if (isset($project['parent']))
array_push($projTree['children'], $project);
$projTree['id'] = $project['parent']['id'];
}
But that overwrites the previous inserted element. I also tried to walk it recursively, but couldn't figure out the correct callback for that, since it only operates on the leafs of the tree and I need to fully walk it.
How can I do this? Thanks!
Please try like below:-
<?php
$array = Array(
'0' => Array
(
'id' => 14,
'name' => 'Foo Directory'
),
'1' => Array
(
'id' => 16,
'name' => 'Bar Project',
'parent' => Array
(
'id' => 14,
'name' => 'Foo Directory'
)
),
'2' => Array
(
'id' => 20,
'name' => 'Baz Project',
'parent' => Array
(
'id' => 16,
'name' => 'Bar Project'
)
),
'3' => Array
(
'id' => 10,
'name' => 'Qux Project',
'parent' => Array
(
'id' => 16,
'name' => 'Bar Project'
)
)
);
$new_array = array();
$i = 0;
$j = 0;
foreach ($array as $key=>$val){
if(array_key_exists('parent',$val)){
foreach($new_array as $key1=>$val1){
if($val['parent']['name'] === $val1['name']){
$new_array[$key1]['children'][$i]['id'] = $val['id'];
$new_array[$key1]['children'][$i]['name'] = $val['name'];
}else{
foreach ($val1['children'] as $key3=>$val3){
if($val['parent']['name'] === $val3['name']){
$new_array[$key1]['children'][$key3]['children'][$j]['id'] = $val['id'];
$new_array[$key1]['children'][$key3]['children'][$j]['name'] = $val['name'];
}
$j++;
}
$i++;
}
}
}else{
$new_array[$key] = $val;
}
}
echo "<pre/>";print_r($new_array);
Output:- https://eval.in/419591
i've a similar array:
Array
(
[0] => Array
(
[id] => 1
[name] => Mario
[type] => Doctor
[operations] => brain
[balance] => 3.00
)
[1] => Array
(
[id] => 3
[name] => Luca
[type] => Doctor
[operations] => hearth
[balance] => 6.00
)
[2] => Array
(
[id] => 3
[name] => Luca
[type] => Doctor
[operations] => hands
[balance] => 4.00
)
[3] => Array
(
[id] => 3
[name] => Luca
[type] => Doctor
[operations] => foots
[balance] => 1.00
)
)
I must to merge it for id, so obtain only 2 elements for array (0 and 1) and Luca (id 3) must be unified for operations, in a new array, similar to this, so in future print more clearly operations unified and not divided.
[...]
)
[1] => Array
(
[id] => 3
[name] => luca
[type] => doctore
[operations] => Array (6.00 hearts,
4.00 hands,
1.00 foots)
)
I can not figure how solve my trouble... Someone could help me please? Thank you very much to all!
<?php
$input = array(
array('id' => 1, 'name' => 'Mario', 'type' => 'Doctor', 'operations' => 'brain', 'balance' => 3.00),
array('id' => 3, 'name' => 'Luca', 'type' => 'Doctor', 'operations' => 'hearth', 'balance' => 6.00),
array('id' => 3, 'name' => 'Luca', 'type' => 'Doctor', 'operations' => 'hands', 'balance' => 4.00),
array('id' => 3, 'name' => 'Luca', 'type' => 'Doctor', 'operations' => 'foots', 'balance' => 1.00),
);
$output = array();
foreach ($input as $person)
{
// Add the person to the output, if needed.
if (array_key_exists($person['id'], $output) === false)
{
$output[$person['id']] =
array(
'id' => $person['id'],
'name' => $person['name'],
'type' => $person['type'],
'operations' => array(),
);
}
// Add the operation to the array of operations.
$output[$person['id']]['operations'][] =
array(
'type' => $person['operations'],
'balance' => $person['balance'],
));
}
foreach ($output as $person)
{
if (count($person['operations']) === 1)
{
// If the array contains only 1 item, pull it out of the array.
$output[$person['id']]['operations'] = $person['operations'][0];
}
}
print_r($output);