Am totally confused with the multidimensional arrays in php. I have a very big array in which am trying to do some search. That is if the colour is green, check for the age and resultant array should contain 4 highest value of age with colour green and all other subarrays should be unaffected. Please help
Array
(
[0] => Array
(
[name] => arr1
[data] => Array
(
[0] => Array
(
[name] => A
[age] => 5
[color] => green
)
[1] => Array
(
[name] => B
[age] => 4
[color] => green
)
[2] => Array
(
[name] => C
[age] => 10
[color] => Red
)
[3] => Array
(
[name] => F
[age] => 1
[color] => green
)
)
)
[1] => Array
(
[name] => arr2
[data] => Array
(
[0] => Array
(
[name] => cc
[age] => 8
[color] => yellow
)
[1] => Array
(
[name] => Y
[age] => 20
[color] => green
)
[2] => Array
(
[name] => Y
[age] => 9
[color] => green
)
)
)
)
Expected resultant array is
Array
(
[0] => Array
(
[name] => arr1
[data] => Array
(
[0] => Array
(
[name] => A
[age] => 5
[color] => green
)
[1] => Array
(
[name] => B
[age] => 4
[color] => green
)
[2] => Array
(
[name] => C
[age] => 10
[color] => Red
)
)
)
[1] => Array
(
[name] => arr2
[data] => Array
(
[0] => Array
(
[name] => cc
[age] => 8
[color] => yellow
)
[1] => Array
(
[name] => Y
[age] => 20
[color] => green
)
[2] => Array
(
[name] => Y
[age] => 9
[color] => green
)
)
)
)
<?php
// Your code here!
$ar[0] = array('name' => 'arr1',
'data' => array
(
'0' => array
(
'name' => 'A',
'age' => 5,
'color' => 'green'
),
'1' => array
(
'name' => 'B',
'age' => 4,
'color' => 'green'
),
'2' => array
(
'name' => 'C',
'age' => 10,
'color' => 'Red'
),
'3' => array
(
'name' => 'F',
'age' => 1,
'color' => 'green'
)
)
);
$ar[1] = array
(
'name' => 'arr2',
'data' => array
(
'0' => array
(
'name' => 'cc',
'age' => 8,
'color' => 'yellow'
),
'1' => array
(
'name' => 'Y',
'age' => 20,
'color' => 'green'
),
'2' => array
(
'name' => 'Y',
'age' => 9,
'color' => 'green'
)
)
);
$green = array();
foreach($ar as $k1=>$a1){
foreach($a1['data'] as $k2=>$a2){
if($a2['color']=='green') {
array_push($green,$a2['age']);
}
}
}
rsort($green);
$green = array_splice($green,0,4);
foreach($ar as $k1=>$a1){
foreach($a1['data'] as $k2=>$a2){
if($a2['color']=='green') {
if(!in_array($a2['age'], $green)){
unset($ar[$k1]['data'][$k2]);
}
}
}
}
print_r($ar);
?>
Related
i have two separate arrays $first_one:
Array
(
[0] => Array
(
[_date] => 2019-10-16
[_number] => 1
[_order] => 1
[name] => jack
[other_ids] => Array
(
[b_id] => 1253
)
)
[1] => Array
(
[_date] => 2020-10-11
[_number] => 2
[_order] => 2
[name] => joey
[other_ids] => Array
(
[b_id] => 1433
)
)
)
and the $second_array:
Array
(
[0] => Array
(
[date] => 2019-10-16
[number] => 1
[order] => 1
[name] => jack
[last_name] => foobar
[other_ids] => Array
(
[b_id] => 1253
)
)
[1] => Array
(
[date] => 2020-10-11
[number] => 2
[order] => 2
[name] => joey
[last_name] => foobar
[other_ids] => Array
(
[b_id] => 1433
)
)
[2] => Array
(
[date] => 2020-10-28
[number] => 3
[order] => 3
[name] => tom
[last_name] => foobar
[other_ids] => Array
(
[b_id] => 1593
)
)
)
they are very similar but they came from different api's and they are different in numbers and also some key names.
so what i'm trying to do is to count the $first_one arrays and if for that many loop through the $second_one (in this example is 2) and if the [_number] [_order] from $first_one was equal (==) to [number] [number] $second_one then take some info (for example the last name) from it and put in a new array.
so is this possible to do?
$arr1 = [ [ '_date' => '2019-10-16','_number' => 1,'_order' => 1,
'name' => 'jack','other_ids' => ['b_id' => 1253]
],
['_date' => 2020-10-11,'_number' => 2,'_order' => 2,
'name' => 'joey','other_ids' => ['b_id' => 1433]
]
];
$arr2 = [ [ 'date' => '2019-10-16','number' => '1','order' => '1',
'name' => 'jack','last_name' => 'foobar','other_ids' => ['b_id' => 1253]
],
[ 'date' => '2019-10-11','number' => '2','order' => '2',
'name' => 'joey','last_name' => 'foobar','other_ids' => ['b_id' => 1433]
],
[ 'date' => '2019-10-28', 'number' => '3', 'order' => '3',
'name' => 'tom', 'last_name' => 'foobar', 'other_ids' => ['b_id' => 1593]
],
];
// first make second array more directly searchable
// make new array with the `number` as the key
foreach( $arr2 as $a){
$arr2new[$a['number']] = $a;
}
foreach ($arr1 as $a) {
if ( array_key_exists($a['_number'], $arr2new) &&
$a['_order'] == $arr2new[$a['_order']]['order'] )
{
$merged[] = ['name'=>$a['name'], 'other_ids' => $a['other_ids']];
}
}
print_r($merged);
RESULT
Array
(
[0] => Array (
[name] => jack
[other_ids] => Array
(
[b_id] => 1253
)
)
[1] => Array (
[name] => joey
[other_ids] => Array
(
[b_id] => 1433
)
)
)
Im trying to remove the duplicate array value group based on the same dates(only keep 1 group).
Also take the number in the "1" key (above the pid key) and add it together with the duplicated grouped.
The issue im having is the each group under hour is "only" supposes to filter with duplicate groups under the same "hour" section.
Here's the array im starting with:
Array(
[1488] => Array
(
[hours] => Array
(
[0] => Array
(
[0] => 2016/07/11 - 2016/07/17
[1] => 37
[pid] => 1488
)
[1] => Array
(
[0] => 2016/07/04 - 2016/07/10
[1] => 51
[pid] => 1488
)
[2] => Array
(
[0] => 2016/07/04 - 2016/07/10
[1] => 44
[pid] => 1488
)
[3] => Array
(
[0] => 2016/07/04 - 2016/07/10
[1] => 22
[pid] => 1488
)
)
)
[2] => Array
(
[hours] => Array
(
[0] => Array
(
[0] => 2016/07/04 - 2016/07/10
[1] => 9.5
[pid] => 2
)
[1] => Array
(
[0] => 2016/07/04 - 2016/07/10
[1] => 8
[pid] => 2
)
[2] => Array
(
[0] => 2016/07/04 - 2016/07/10
[1] => 7
[pid] => 2
)
[3] => Array
(
[0] => 2016/07/11 - 2016/07/17
[1] => 5
[pid] => 2
)
)
)
)
Here what i need it to look like:
Array(
[0] => Array
(
[hours] => Array
(
[0] => Array
(
[0] => 2016/07/11 - 2016/07/17
[1] => 37
[pid] => 1488
)
[1] => Array
(
[0] => 2016/07/04 - 2016/07/10
[1] => 117
[pid] => 1488
)
)
)
[1] => Array
(
[hours] => Array
(
[0] => Array
(
[0] => 2016/07/04 - 2016/07/10
[1] => 24.5
[pid] => 2
)
[1] => Array
(
[0] => 2016/07/11 - 2016/07/17
[1] => 5
[pid] => 2
)
)
)
)
This is my code:
$temp_array = array();
$w = 0;
$key_array = array();
$new_array = array();
foreach($project_hours as $old_arrs) {
foreach ($old_arrs["hours"] as $val) {
if (!in_array($val[0], $key_array)) {
$key_array[$w] = $val[0];
$temp_array[$w] = $val;
} else {
$ser = array_search($val[0], $key_array);
$temp_array[$ser][1] += $val[1];
}
$w++;
$old_arrs["hours"] = $temp_array;
}
$new_array[] = $old_arrs;
}
echo '<pre>';
print_r($new_array);
echo '</pre>';
You can just do some simple tricks to organize the array keys, then use array_values() in two areas to reset the associative keys to numeric keys:
// Your array
$data = array(
1488 => array(
'hours' => array(
0 => array(
0 => '2016/07/11 - 2016/07/17',
1 => 37,
'pid' => 1488,
),
1 => array(
0 => '2016/07/04 - 2016/07/10',
1 => 51,
'pid' => 1488
),
2 => array(
0 => '2016/07/04 - 2016/07/10',
1 => 44,
'pid' => 1488
),
3 => array(
0 => '2016/07/04 - 2016/07/10',
1 => 22,
'pid' => 1488
)
)
),
2 => array(
'hours' => array(
0 => array(
0 => '2016/07/04 - 2016/07/10',
1 => 9.5,
'pid' => 2
),
1 => array(
0 => '2016/07/04 - 2016/07/10',
1 => 8,
'pid' => 2
),
2 => array(
0 => '2016/07/04 - 2016/07/10',
1 => 7,
'pid' => 2
),
3 => array(
0 => '2016/07/11 - 2016/07/17',
1 => 5,
'pid' => 2
)
)
)
);
// Loop through array...
foreach($data as $pid => $group) {
foreach($group['hours'] as $row) {
// I am using the date as a unique key so it's easy to organize
$new[$pid]['hours'][$row[0]][0] = $row[0];
// This will draw an warning if you don't first check that it's set
if(!isset($new[$pid]['hours'][$row[0]][1]))
$new[$pid]['hours'][$row[0]][1] = 0;
// Add values together as you go
$new[$pid]['hours'][$row[0]][1] += $row[1];
// On each loop this just assigns the pid (it just keeps overwriting itself
// but that is no big deal)
$new[$pid]['hours'][$row[0]]['pid'] = $pid;
}
// Here since you are not using date keys, just reset to numeric
$new[$pid]['hours'] = array_values($new[$pid]['hours']);
}
print_r(array_values($new));
Gives you:
Array
(
[0] => Array
(
[hours] => Array
(
[0] => Array
(
[0] => 2016/07/11 - 2016/07/17
[1] => 37
[pid] => 1488
)
[1] => Array
(
[0] => 2016/07/04 - 2016/07/10
[1] => 117
[pid] => 1488
)
)
)
[1] => Array
(
[hours] => Array
(
[0] => Array
(
[0] => 2016/07/04 - 2016/07/10
[1] => 24.5
[pid] => 2
)
[1] => Array
(
[0] => 2016/07/11 - 2016/07/17
[1] => 5
[pid] => 2
)
)
)
)
This is my array.
Array
(
[id] => 1
[color] => "White"
[something] => Array
(
[country] => "France"
[city] => "Paris"
)
)
Array
(
[id] => 2
[color] => "Black"
[something] => Array
(
[country] => "Germany"
[city] => "Berlin"
)
)
Array
(
[id] => 2
[color] => "Red"
[something] => Array
(
[country] => "Russia"
[city] => "Moscow"
)
)
I want to group arrays with same id value. This should be the output:
[0] => Array
(
[0] => Array
(
[id] => 1
[color] => "White"
[something] => Array
(
[country] => "France"
[city] => "Paris"
)
)
)
[1] => Array
(
[0] => Array
(
[id] => 2
[color] => "Black"
[something] => Array
(
[country] => "Germany"
[city] => "Berlin"
)
)
[1] => Array
(
[id] => 2
[color] => "Red"
[something] => Array
(
[country] => "Russia"
[city] => "Moscow"
)
)
)
I tried with tens of foreach statements but there's no way for me to get arrays with same id inside the same array. Is it probably related with the fact that it's a multidimensional array? Should I use 2 nested foreach to get the result?
Code:
<?php
$arr = array(
array(
'id' => 1,
'color' => 'white',
'something' => array(
'country' => 'France',
'city' => 'Paris',
),
),
array(
'id' => 2,
'color' => 'Black',
'something' => array(
'country' => 'Germany',
'city' => 'Berlin',
),
),
array(
'id' => 2,
'color' => 'Red',
'something' => array(
'country' => 'Russia',
'city' => 'Moscow',
),
),
);
function groupify($arr) {
$new = array();
foreach ($arr as $item) {
if (!isset($new[$item['id']])) {
$new[$item['id']] = array();
}
$new[$item['id']][] = $item;
}
return $new;
}
print_r(groupify($arr));
Result:
Array
(
[1] => Array
(
[0] => Array
(
[id] => 1
[color] => white
[something] => Array
(
[country] => France
[city] => Paris
)
)
)
[2] => Array
(
[0] => Array
(
[id] => 2
[color] => Black
[something] => Array
(
[country] => Germany
[city] => Berlin
)
)
[1] => Array
(
[id] => 2
[color] => Red
[something] => Array
(
[country] => Russia
[city] => Moscow
)
)
)
)
if you don't want to preserve keys, just call array_values before return.
Use id for key of new array.
$a[$array[id]][] = $array;
If you wanted to use a foreach:
<?php
$return = array();
foreach($array as $key => $innerArray) {
$return[$innerArray['id']][]= $innerArray;
}
Now $return contains them groped by ID, where keys 1 and 2 are your IDs
array(
1 => array(
array(/** **/)
),
2 => array(
array(/** **/),
array(/** **/)
);
);
You can then access your groups like this:
foreach($return as $key => $groupArray) {
// you have the groups here
foreach($groupArray as $id => $singleArray) {
// singleArray contains your id, colour etc
}
}
foreach($return[1] as $groupOne) {
// all arrays with id = 1
}
Array
(
[12] => Array
(
[id] => 12
[name] => Car
[children] => Array
(
[0] => Array
(
[id] => 14
[name] => Volvo
)
[1] => Array
(
[id] => 15
[name] => Mercedes-Benz
)
)
)
[13] => Array
(
[id] => 13
[name] => Manga
[children] => Array
(
[0] => Array
(
[id] => 16
[name] => Naruto
)
[1] => Array
(
[id] => 17
[name] => Hunter X Hunter
)
)
)
[18] => Array
(
[id] => 18
[name] => aa
[children] => Array
(
)
)
)
Guys I want to sort the values of this array, i want to sort it by key and the key is 'name'. This should sort the first level and the second level thru key 'name'.
This array i put in print_r() so it looks like this. The array is not fix so i can add in the future.
So after sorting the final value of the array is...
Array
(
[18] => Array
(
[id] => 18
[name] => aa
[children] => Array
(
)
)
[12] => Array
(
[id] => 12
[name] => Car
[children] => Array
(
[0] => Array
(
[id] => 15
[name] => Mercedes-Benz
)
[1] => Array
(
[id] => 14
[name] => Volvo
)
)
)
[13] => Array
(
[id] => 13
[name] => Manga
[children] => Array
(
[0] => Array
(
[id] => 17
[name] => Hunter X Hunter
)
[1] => Array
(
[id] => 16
[name] => Naruto
)
)
)
)
And this is the array in code.
$categories = array(
12 =>
array('id' =>12,
'name' => 'Car',
'children' =>
array(
array('id' => 14,
'name' => 'volvo'
)
),
array(
array('id' => 15,
'name' => 'Mercedez-Benz'
)
)
),
13 =>
array('id' =>13,
'name' => 'Manga',
'children' =>
array(
array('id' => 16,
'name' => 'Naruto'
)
),
array(
array('id' => 17,
'name' => 'Hunter X Hunter'
)
)
),
18=>
array('id' => 18,
'name'=> 'aa',
'children' => array())
);
echo "<pre>";
print_r($categories);
the 'name' is not your real 'Key', just saying, because 'key' in Php normally means the name of your array, like '18' and '12' in your array and so on, like this:
<?php
$fruits = array("d"=>"lemon", "a"=>"orange", "b"=>"banana", "c"=>"apple");
ksort($fruits);
foreach ($fruits as $key => $val) {
echo "$key = $val\n";
}
?>
in this example, the result will be:
a = orange
b = banana
c = apple
d = lemon
anyway to answer your question on how to sort it on 'name', use 'usort':
function cmp($a, $b) {
return $a['name'] - $b['name'];
}
usort($arr,"cmp");
check out the following link for further information:
How do I sort a PHP array by an element nested inside?
if using php 5.3+ you can use closures in your code and sort like this
usort($categories,function($a,$b){
return $a['name'] - $b['name']
}
So,
I'm going to try and explain it better to you
your array is big, yes, but you want to sort only on the key value '[name]'.
In my test I used the array you provided:
$categories = array(
12 =>
array('id' =>12,
'name' => 'Car',
'children' =>
array(
array('id' => 14,
'name' => 'volvo'
)
),
array(
array('id' => 15,
'name' => 'Mercedez-Benz'
)
)
),
13 =>
array('id' =>13,
'name' => 'Manga',
'children' =>
array(
array('id' => 16,
'name' => 'Naruto'
)
),
array(
array('id' => 17,
'name' => 'Hunter X Hunter'
)
)
),
18=>
array('id' => 18,
'name'=> 'aa',
'children' => array())
);
if the array is declared, you can add the usort like this:
usort($categories,"sortByName");
the first element in the above ($categories), is your array, the second element will provide the name of a function, in this case 'sortByName'.
after that, you just add a function into your code (it doesn't really matter where you put it, even if it's at the bottom of the page):
function sortByName($categories, $b) {
return strcasecmp($categories["name"], $b["name"]);
}
Basically what this function does, is compairing your array with ...your array :) so it can sort it alfabetically by name- like you want it.
sthe 'strcasecmp' is to compare your strings against eachother to sort it. not that this is case non sensitive (strcmp will be case sensitive too). I assume you don't want it to check on uppercase and so on too, otherwise the result won't be what you wanted.
when you added that code, you can just print your array again:
echo "<pre>";
print_r($categories);
your result will be:
Array
(
[0] => Array
(
[id] => 18
[name] => aa
[children] => Array
(
)
)
[1] => Array
(
[id] => 12
[name] => Car
[children] => Array
(
[0] => Array
(
[id] => 14
[name] => volvo
)
)
[0] => Array
(
[0] => Array
(
[id] => 15
[name] => Mercedez-Benz
)
)
)
[2] => Array
(
[id] => 13
[name] => Manga
[children] => Array
(
[0] => Array
(
[id] => 16
[name] => Naruto
)
)
[0] => Array
(
[0] => Array
(
[id] => 17
[name] => Hunter X Hunter
)
)
)
I hope this is what you wanted. :-)
I have a multidimensional Array like this:
Array (
[0] => Array (
[id] => 1
[name] => privilages1
)
[1] => Array (
[id] => 2
[name] => privilages2
)
[2] => Array (
[id] => 3
[name] => privilages3
)
[3] => Array (
[id] => 4
[name] => privilage4 )
[4] => Array (
[id] => 5
[name] => privilages5 )
)
and i want to compare it with another array, which looks like this:
Array (
[0] => Array (
[id] => 1 )
[1] => Array (
[id] => 2)
)
if the value of id matches, then i want to all values from the first example.
How can i do this?
You can use array_filter to filter the array elements you want by supplying a user defined callback function.
Here is the code:
$arr = array( array('id' => 1, 'name' => 'foo'),
array('id' => 2, 'name' => 'bar'),
array('id' => 3, 'name' => 'baz'),
array('id' => 4, 'name' => 'wow'));
$ret = array_filter($arr, create_function('$el',
'static $search=array(array("id" => 1), array("id" => 2));
$n=array("id" => $el["id"]);
return (array_search($n, $search) !== false);'));
print_r($ret);
OUTPUT
Array
(
[0] => Array
(
[id] => 1
[name] => foo
)
[1] => Array
(
[id] => 2
[name] => bar
)
)