Multidimensional Array Filtering PHP - php

This is my array:
Array ( [0] => Array ( [license_id] => 172 [valid_from] => 2014-10-13 14:39:32 [valid_till] => 2020-10-22 00:00:00 [us_user_user_id] => 810 [us_group_group_id] => [li_voucher_voucher_id] => 90128 [pr_product_product_ids] => 91,92,93 [li_license_setting_license_setting_id] => 55 [li_voucher_setting_voucher_setting_id] => 222 [product_data] => {"answer_layer":true} ) [1] => Array ( [license_id] => 173 [valid_from] => 2014-10-13 14:39:48 [valid_till] => 2020-10-21 14:39:48 [us_user_user_id] => 810 [us_group_group_id] => [li_voucher_voucher_id] => 90129 [pr_product_product_ids] => 94 [li_license_setting_license_setting_id] => 73 [li_voucher_setting_voucher_setting_id] => 223 [product_data] => {"answer_layer":true} ) [2] => Array ( [license_id] => 371 [valid_from] => 2015-01-07 12:05:36 [valid_till] => 2021-01-15 12:05:36 [us_user_user_id] => 810 [us_group_group_id] => [li_voucher_voucher_id] => 89008 [pr_product_product_ids] => 173 [li_license_setting_license_setting_id] => 56 [li_voucher_setting_voucher_setting_id] => 160 [product_data] => {"answer_layer":true} ) [3] => Array ( [license_id] => 441 [valid_from] => 2015-03-04 16:10:18 [valid_till] => 2016-03-03 16:10:18 [us_user_user_id] => 810 [us_group_group_id] => [li_voucher_voucher_id] => 124457 [pr_product_product_ids] => 243 [li_license_setting_license_setting_id] => 201 [li_voucher_setting_voucher_setting_id] => 315 [product_data] => ) )
I want to filter the the value [valid_till] where the value from [license_id] = 441.
I already filtered the specific license with license_id 441 with the next code:
$filtered = array_filter($userlicenses, function($v) { return $v['license_id'] == '441'; });
But this gives me the complete array. I want only the [valid_till] where [license_id] = 441.

array_reduce is an easy way to just return the value:
$result = array_reduce($userlicenses,
function($c, $v) {
return $v['license_id'] == '441' ? $v['valid_till'] : false;
}
);
And an array_column method:
$result = array_column($userlicenses, 'valid_from', 'license_id')[441];

"Iterates over each value in the array passing them to the callback function. If the callback function returns true, the current value from array is returned into the result array. Array keys are preserved." function.array-filter
This means your variable $filtered is an array again/still.
If it's only one dimensional (i.e. you have always exactly one result) you can simply access the key valid_till of the first element returned this way:
<?php
$userlicenses = array(
0 => array (
'license_id' => 172,
'valid_from' => '2014-10-13 14:39:32',
'valid_till' => '2020-10-22 00:00:00'
),
1 => array (
'license_id' => 173,
'valid_from' => '2014-10-13 14:39:48',
'valid_till' => '2020-10-21 14:39:48'
),
2 => array (
'license_id' => 371,
'valid_from' => '2015-01-07 12:05:36',
'valid_till' => '2021-01-15 12:05:36'
),
3 => array (
'license_id' => 441,
'valid_from' => '2015-03-04 16:10:18',
'valid_till' => '2016-03-03 16:10:18'
)
);
$filtered = array_filter($userlicenses, function($v) { return $v['license_id'] == '441'; });
var_dump( $filtered );
if( is_array( $filtered ) )
{
$first_el = reset( $filtered );
$valid_till = $first_el['valid_till'];
var_dump( $valid_till );
}
?>

Related

Array_map when elements are shuffled

I have this array (it's just a part of it). 6 = question ID, optionIDs = possible answers.
Array
(
[3] => Array
(
[0] => 6
[1] => Array
(
[0] => Array
(
[optionID] => 16
[isCorrect] => 0
)
[1] => Array
(
[optionID] => 14
[isCorrect] => 1
)
[2] => Array
(
[optionID] => 15
[isCorrect] => 0
)
[3] => Array
(
[optionID] => 17
[isCorrect] => 0
)
)
)
[7] => Array
(
[0] => 6
[1] => Array
(
[0] => Array
(
[optionID] => 16
[isCorrect] => 0
)
[1] => Array
(
[optionID] => 15
[isCorrect] => 0
)
[2] => Array
(
[optionID] => 17
[isCorrect] => 0
)
[3] => Array
(
[optionID] => 14
[isCorrect] => 1
)
)
)
)
I'm trying to merge redundant questions (6 and 6) with array_map:
$unique = array_map('unserialize', array_unique(array_map('serialize', $quizQuestionArray)));
And it works as long as optionIDs are in the same order. But in some cases (like here) they are shuffled (16,14,15,17) (16,15,17,14). Is there a way to keep them shuffled and remove duplicate questions?
array_map-serialize is a pretty crude way to deduplicate an array. You should be using something like this instead:
$dupeIds = [];
$array = array_filter($array, function ($item) use (&$dupeIds) {
$keep = !isset($dupeIds[$item[0]]);
$dupeIds[$item[0]] = true;
return $keep;
});
You will need to sort them to the same order before applying you array_map() function. You can use the uasort() function and supply your own comparison function like this:
// Example array
$array = array(
3 => array(
0 => 6,
1 => array(
0 => array(
'optionID' => 16,
'isCorrect' => 0
),
1 => array(
'optionID' => 14,
'isCorrect' => 1
),
2 => array(
'optionID' => 15,
'isCorrect' => 0
),
3 => array(
'optionID' => 17,
'isCorrect' => 0
),
)
),
7 => array(
0 => 6,
1 => array(
0 => array(
'optionID' => 16,
'isCorrect' => 0
),
1 => array(
'optionID' => 15,
'isCorrect' => 0
),
2 => array(
'optionID' => 17,
'isCorrect' => 0
),
3 => array(
'optionID' => 14,
'isCorrect' => 1
),
)
)
);
// You can supply parts of an array to uasort()
// uasort() will modify your array but keep your keys.
uasort($array[3][2], 'sort_by_optionid');
uasort($array[7][3], 'sort_by_optionid');
function sort_by_optionid($a, $b) {
if ($a['optionID'] === $b['optionID']) {
return 0;
} else if ($a['optionID'] > $b['optionID']) {
return 1;
} else {
return -1;
}
}
// Done.
Now the keys are preserved and you can easily array_map() to find the duplicates and then sort again back to the original state according to the keys. E.g. with uksort()

Codeigniter XML-RPC Response Multi Dimensional Array Approach

I need to create an XML-RPC server that gets cities with their corresponding IDs. What I do as a response is looking weird to me because of unnecessary duplicate entries but I couldnt find a better way.
Array
(
[cityID] => Array
(
[0] => 34
[1] => 35
[2] => 06
)
[cityName] => Array
(
[0] => Istanbul
[1] => Izmir
[2] => Ankara
)
)
I implemented above response. With this implementation:
$response = array(
array(
'cityID' => array(array('34', '35', '06'), 'array'),
'cityName' => array(array('Istanbul', 'Izmir', 'Ankara'), 'array')
),
'struct'
);
The problem is I want to take a response like this :
Array
(
[cities] => Array
(
['34'] => 'Istanbul'
['35'] => 'Izmir'
['06'] => 'Ankara'
)
)
So I tried to implement it like this :
$response = array(
array(
'cities' => array(array('34'=>'Istanbul', '35'=>'Izmir', '06'=>'Ankara'), 'array')
),
'struct'
);
But it fails with this implementation. What am I doing wrong ?
Thanks
You have array like following
$response = array ( 'cityID' => array (
0 => 34,
1 => 35,
2 => 06
),
'cityName' => array(
0 => 'Istanbul',
1 => 'Izmir',
2 => 'Ankara'
)
);
$newarray = array();
foreach($response['cityID'] as $key => $cityid){
$newarray['cities'][$cityid] = $response['cityName'][$key];
}
print_r($newarray);
You will be getting the expected array.
Array
(
[cities] => Array
(
[34] => Istanbul
[35] => Izmir
[6] => Ankara
)
)
This is how I do it, in Code Igniter 3
$array = array ( 'cityID' => array (
0 => 34,
1 => 35,
2 => 06
),
'cityName' => array(
0 => 'Istanbul',
1 => 'Izmir',
2 => 'Ankara'
)
);
foreach($array['cityID'] as $key => $cityid){
$response[] = array(array(
$cityid => array($array['cityName'][$key],'string'),
),'struct');
}
return $this->xmlrpc->send_response(array($response,'array'));

Group php array by date and sum another column's values

I have an array:
Array
(
[0] => Array
(
[id] => 81
[placed] => 2013-09-19 16:32:53
[sub_total] => 786
)
[1] => Array
(
[id] => 80
[placed] => 2013-09-19 16:32:06
[sub_total] => 780
)
[2] => Array
(
[id] => 79
[placed] => 2013-09-18 17:06:48
[sub_total] => 786
)
[3] => Array
(
[id] => 78
[placed] => 2013-09-18 17:05:02
[sub_total] => 756
)
[4] => Array
(
[id] => 77
[placed] => 2013-09-17 17:02:53
[sub_total] => 786
)
[5] => Array
(
[id] => 76
[placed] => 2013-09-16 17:02:53
[sub_total] => 756
)
)
Is it possible to group this data by date and summarize subtotal amount to get output array:
Array
(
[0] => Array
(
[placed] => 2013-09-19
[sub_total] => 786 + 780
)
[2] => Array
(
[placed] => 2013-09-18
[sub_total] => 786 + 756
)
[3] => Array
(
[placed] => 2013-09-17 17:02:53
[sub_total] => 786
)
[4] => Array
(
[placed] => 2013-09-16 17:02:53
[sub_total] => 756
)
)
$output=array();
foreach($yourArray as $values)
{
$d=date("Y-m-d",strtotime($values["placed"]));
$output[$d]["sub_total"]+=$values["sub_total"];
}
print_r($output);
Fiddle
Credits: The initial array used on this fiddle was taken from the answer by Jason OOO below.
I tested this also: http://phpfiddle.org/main/code/rzv-ngp
<?php
Array
(
'0' => Array
(
'id' => '81',
'placed' => '2013-09-19 16:32:53',
'sub_total' => '786'
),
'1' => Array
(
'id' => '80',
'placed' => '2013-09-19 16:32:06',
'sub_total' => '780'
),
//...
);
$newarray = array();
foreach ($array as $value){
$temp = explode(" ", $value['placed']);
$date = $temp[0];
$total = (isset($newarray[$date]['sub_total']) ? $newarray[$date]['sub_total'] + $value['sub_total']: $value['sub_total']);
$newarray[$date] = array('placed' => $date, 'sub_total' => $total);
}
print_r($newarray);
?>
You can have that kind of array at querying time. Something like
select date_field_name,other_field from table_name group by Day(date_feild_name);
after that you can use a use foreach to work with each day's data!
Try using sub query
select field_name,DAY(date_field) as date,(select sum(sub_total) where DAY(date_field)=date) as sub_total from table_name group by day(date_field)
Try this code
<?php
$shop = array(array( id => '81',
placed => '2013-09-19',
sub_total => '786'
),
array( id =>'80',
placed => '2013-09-19',
sub_total => '780',
),
array( id => '79',
placed => '2013-09-18',
sub_total => '786'
),
array
(
id => '78',
placed => '2013-09-18',
sub_total => '756'
),
array(
id => '77',
placed => '2013-09-17',
sub_total => '786'
),
array(
id => '76',
placed => '2013-09-16',
sub_total => '756'
)
);
$result=array();
foreach($shop as $value)
{
if(!isset($result[$value['placed']]))
{
//echo $value['placed'];
//echo $result[$value['placed']];
$result[$value['placed']]=array('placed'=>$value['placed'],'sub_total'=>0);
}
$result[$value['placed']]['sub_total']+=$value['sub_total'];
}
print_r($result);
//print_r($shop);
?>

PHP - compare and filter two arrays with different dimensions

I am trying to filter two arrays to get a final result with user ids from my mysql database
I have two arrays the first one:
print_r($arr_partner_id);
Array (
[0] => Array ( [id] => 335 [id_partner] => 0 )
[1] => Array ( [id] => 469 [id_partner] => 1 )
[2] => Array ( [id] => 457 [id_partner] => 1 )
[3] => Array ( [id] => 339 [id_partner] => 0 )
[4] => Array ( [id] => 361 [id_partner] => 0 ) )
and the second one:
print_r($arr_member_id);
Array (
[0] => 457
[1] => 469
[2] => 339
[3] => 361 )
now i want compare these two only with their ids and delete the ids that are not included in the "$arr_member_id" Array. This my "reference Array" that means i only need the ids (457,469,339,361)
for the final result it should be looking like this:
print_r($arr_partner_final_id);
Array (
[0] => Array ( [id] => 469 [id_partner] => 1 )
[1] => Array ( [id] => 457 [id_partner] => 1 )
[2] => Array ( [id] => 339 [id_partner] => 0 )
[3] => Array ( [id] => 361 [id_partner] => 0 ) )
i tryed it with foreach
foreach ($arr_partner_id as $key => $usr_ids) {
if($arr_partner_id[$key]['id'] == $arr_member_id[$key]) {
// do something
}
}
but the "keys" are different this should not working...
making it as simple, and using just one loop to loop through the array and checkin if the id is present in another set of array using in_array()
try this
for($i=0;$i<count($arr_partner_id);$i++){
if(!in_array($arr_partner_id[$i]['id'],$arr_member_id)){
unset($arr_partner_id[$i]);
}
}
print_r($arr_partner_id);
try it here
AND yes!! if you want seperate arrays for that then simply modify the code..create new array and push the elements that is present in array
$finalArray=array();
for($i=0;$i<count($arr_partner_id);$i++){
if(in_array($arr_partner_id[$i]['id'],$arr_member_id)){
$finalArray[]=$arr_partner_id[$i];
}
}
print_r($finalArray);
Try this (Working example : http://codepad.org/ApFcA3Zo)
<?php
$arr_partner_id=array (
'0' => array ( 'id' => 335, 'id_partner' => 0 ) ,
'1' => array ( 'id' => 469, 'id_partner' => 1 ) ,
'2' => array ( 'id' => 457, 'id_partner' => 1 ) ,
'3' => array ( 'id' => 339, 'id_partner' => 0 ) ,
'4' => array ( 'id' => 361, 'id_partner' => 0 ) ) ;
$arr_member_id=array (
'0' => 457 ,
'1' => 469 ,
'2' => 339 ,
'3' => 361 ) ;
$final =array();
foreach($arr_partner_id as $arr)
{
foreach($arr_member_id as $parr)
{
if($arr['id'] == $parr)
{
$final[]=$arr;
}
}
}
print_r($final);
?>
Maybe something like:
foreach ($arr_member_id as $usr_id){
foreach ($arr_partner_id as $partner){
if ($usr_id == $partner['id']) {$arr_partner_final_id[]=$partner;break;
}
}
Another solution (without explicit looping):
$arr_partner_id=array (
'0' => array( 'id' => 335, 'id_partner' => 0 ),
'1' => array( 'id' => 469, 'id_partner' => 1 ),
'2' => array( 'id' => 457, 'id_partner' => 1 ),
'3' => array( 'id' => 339, 'id_partner' => 0 ),
'4' => array( 'id' => 361, 'id_partner' => 0 ));
$arr_member_id=array (
'0' => 457,
'1' => 469,
'2' => 339,
'3' => 361);
function compare($v){global $arr_member_id;return in_array($v['id'], $arr_member_id);}
var_dump($arr_partner_id = array_filter($arr_partner_id, 'compare'));
better you use mysql itself do this task. but if you need to continue with this use in array function to check the second array as given below,
foreach ($arr_partner_id as $key => $usr_ids) {
if(in_array($usr_ids["id"], $arr_member_id)) {
// do something
}
}

reformat multidimensional array based on value

i have an array in below format
$op = Array
(
[0] => Array
(
[0] => Array
(
[contact_id] => 36
[sender_id] => 79
[sendto] => 9192
)
[1] => Array
(
[event_id] => 145
[sender_id] => 9139
[sendto] => 9192
)
)
[1] => Array
(
[0] => Array
(
[event_id] => 145
[sender_id] => 9272
[sendto] => 9290
)
)
[2] => Array
(
[0] => Array
(
[event_id] => 145
[sender_id] => 9138
[sendto] => 9316
)
[1] => Array
(
[event_id] => 145
[sender_id] => 9283
[sendto] => 9316
)
)
)
i want to filter array in a way that resultant array's key should be different sendto values and all sender_id under that sendto shoud come under that array's key
Desired output
Array
(
[9192] => Array
(
[0] =>79
[1] =>9139
)
[9290] =>Array
(
[0]=>9272
)
[9316] =>Array
(
[0] =>9138
[1] =>9283
)
)
although i tried with below code
foreach ($op as $ok=>$ov)
{
if( array_key_exists($ov['sendto'],$mid))
$mid[$ov['sendto']][]=$ok;
else
$mid[$ov['sendto']]=$ok;
}
but this one display notice:Undefined index: sendto
please tell me where i m doing wrong?? i always stuck in such problem
Something like this:
<?php
//Test Array
$op = array(
array(
array(
'contact_id' => 36,
'sender_id' => 79,
'sendto' => 9192
),
array(
'contact_id' => 145,
'sender_id' => 9139,
'sendto' => 9192
)
),
array(
array(
'contact_id' => 145,
'sender_id' => 9272,
'sendto' => 9290
)
),
array(
array(
'contact_id' => 145,
'sender_id' => 9138,
'sendto' => 9316
),
array(
'contact_id' => 145,
'sender_id' => 9283,
'sendto' => 9316
)
),
);
//Switch array format
$new = array();
foreach($op as $element)
{
foreach($element as $entity)
{
if(!isset($new[$entity['sendto']]))
{
$new[$entity['sendto']] = array();
}
$new[$entity['sendto']][] = $entity['sender_id'];
}
}
//Debug the new array.
print_r($new);
Try:
$mid = array();
foreach($op as $tmp_array)
{
foreach($tmp_array as $message)
{
if (!isset($mid[$message['sendto']]))
$mid[$message['sendto']] = array();
$mid[$message['sendto']][] = $message['sender_id'];
}
}
You should go like this:
foreach ($op as $ok=>$ov)
{
if(!array_key_exists('sendto',$mid))
{
$mid[$ov['sendto']] = array();
}
$mid[$ov['sendto']][] = $ov['sender_id'];
}

Categories