php 5.3 convert array_walk_recursive - php

I have the following code, and I'd like to get away from the call-time pass-by-reference, (To convert from 5.2 to 5.3) but I'm not sure exactly sure what the correct way to do this would be (class, global variable, ?)
Here is a codepad that should have everything in it
http://codepad.org/ombgFPMR
<?php
function count_things($item, $key, $total) {
$total++;
}
$counts = array(100 => 1,
101 => 1,
102 => array(
106 => 1,
107 => 1
),
103 => 1,
104 => 1,
105 => array(
108 => 1,
109 => array(
110 => 1,
111 => 1,
112 => 1
)
)
);
foreach($counts as $key => $count) {
$total = 0;
if(is_array($count)) {
$total++;
/* The below is a logic error. Array elements that contain arrays do not get
the callback function called on them. Therefore, any children with children
of their own will not be counted. In the output of this paste,
the final key, $final_counts[105]['total'], should have a value of 6, but it
actually has a value of 5. */
array_walk_recursive($count, 'count_things', &$total);
} else {
$total = $count;
}
$final_counts[$key]['total'] = $total;
}
print_r($final_counts);
?>
Output looks like:
Array
(
[100] => Array
(
[total] => 1
)
[101] => Array
(
[total] => 1
)
[102] => Array
(
[total] => 3
)
[103] => Array
(
[total] => 1
)
[104] => Array
(
[total] => 1
)
[105] => Array
(
[total] => 5
)
)

You can use count with COUNT_RECURSIVE flag.
You should use closures for this, these were introduced in 5.3.0 so they should work.
<?php
$counts = array(
100 => 1,
101 => 1,
102 => array(
106 => 1,
107 => 1
),
103 => 1,
104 => 1,
105 => array(
108 => 1,
109 => array(
110 => 1,
111 => 1,
112 => 1
)
)
);
$final_counts = array();
foreach($counts as $key => $count) {
if(is_array($count)) {
$total = 1;
array_walk_recursive($count, function() use (&$total) {
$total++;
});
} else {
$total = $count;
}
$final_counts[$key]['total'] = $total;
}
print_r($final_counts);
I might be able to provide a better solution if you put your problem in context.

Related

Count multi array rates

Im having troubles counting this.
I want to count all rates than belongs to id_image.
Maybe like key = id_image and value = tot count, id tried with array_count_values, but i cant use it normally when its multi :-S
Array
(
[0] => Array
(
[id_image] => 12
[rate] => 4
)
[1] => Array
(
[id_image] => 13
[rate] => 4
)
[2] => Array
(
[id_image] => 14
[rate] => 3
)
[3] => Array
(
[id_image] => 13
[rate] => 4
)
[4] => Array
(
[id_image] => 12
[rate] => 5
)
[5] => Array
(
[id_image] => 12
[rate] => 4
)
)
// test array
$arr = array(
0 => array(
'id_image' => 1,
'rate' => 3
),
1 => array(
'id_image' => 2,
'rate' => 8
),
2 => array(
'id_image' => 3,
'rate' => 4
),
3 => array(
'id_image' => 1,
'rate' => 2
),
4 => array(
'id_image' => 3,
'rate' => 2
)
);
// put the length in a var so we don't keep calling count();
$length = count($arr);
// the new array that'll hold the sum of the rates
$totals = array();
// iterate through the test array
for ($i = 0; $i < $length; ++$i) {
// check if $totals already contains data for the specified id_image
if (isset($totals[$arr[$i]['id_image']])) {
// if so, add data
$totals[$arr[$i]['id_image']] += $arr[$i]['rate'];
} else {
// if not so, set data
$totals[$arr[$i]['id_image']] = $arr[$i]['rate'];
}
}
var_dump($totals);
Example

unique array on base on value of specific key

I have the following array:
Array
(
[0] => Array
(
[hotelID] => 10
[hotelcategoryID] => 12
[hotelName] => Grand Forest Metsovo
[hotelShortDescription] =>
[hotelVisible] => 1
[roomID] => 2
)
[1] => Array
(
[hotelID] => 10
[hotelcategoryID] => 12
[hotelName] => Grand Forest Metsovo
[hotelShortDescription] =>
[hotelVisible] => 1
[roomID] => 3
)
[2] => Array
(
[hotelID] => 10
[hotelcategoryID] => 12
[hotelName] => Grand Forest Metsovo
[hotelShortDescription] =>
[hotelVisible] => 1
[roomID] => 4
)
[3] => Array
(
[hotelID] => 14
[hotelcategoryID] => 7
[hotelName] => Hotel Metropolis
[hotelShortDescription] =>
[hotelVisible] => 1
[roomID] => 23
)
[4] => Array
(
[hotelID] => 14
[hotelcategoryID] => 7
[hotelName] => Hotel Metropolis
[hotelShortDescription] =>
[hotelVisible] => 1
[roomID] => 24
)
)
I have two different hotelID keys. I would like to extract only one element (the first one) where the hotelID is unique in whole array. I am trying with following code:
$data['uniqueHotels'] = array_map('unserialize', array_unique(array_map('serialize', $hotels)));
but without any luck so far.
Anyone can give me a hint?
If looking for the first element:
<?php
$hotels = array(
array(
'id' => 1,
'hotelID' => 10
),
array(
'id' => 2,
'hotelID' => 10,
),
array(
'id' => 3,
'hotelID' => 20,
),
array(
'id' => 4,
'hotelID' => 20,
),
);
function getUniqueHotels($hotels) {
$uniqueHotels = array();
foreach($hotels as $hotel) {
$niddle = $hotel['hotelID'];
if(array_key_exists($niddle, $uniqueHotels)) continue;
$uniqueHotels[$niddle] = $hotel;
}
return $uniqueHotels;
}
$unique_hotels = getUniqueHotels($hotels);
print_r($unique_hotels);
results in:
Array
(
[10] => Array
(
[id] => 1
[hotelID] => 10
)
[20] => Array
(
[id] => 3
[hotelID] => 20
)
)
You could simply loop through the array and add them to a new array, indexed by hotelID. This way any duplicates will just overwrite the existing value and you end up with one entry per hotel:
$unique = array();
foreach ($hotels as $value)
{
$unique[$value['hotelID']] = $value;
}
$data['uniqueHotels'] = array_values($unique);
Here is a dynmaic solution:
function uniqueAssocArray($array, $uniqueKey){
$unique = array();
foreach ($array as $value){
$unique[$value[$uniqueKey]] = $value;
}
$data = array_values($unique);
return $data;
}
How to use:
uniqueAssocArray($yourArray, 'theKey');
along the lines of what you're trying,
array_unique(array_map(function($hotel) { return $hotel['hotelID']; }, $array))

How to get Sum of Associative array having specific key and value in php

I have to fetch sum of Amount field from given associative array according to TXNLineNo.
Array
(
[0] => Array
(
[TXNID] => 0
[RefTXNID] => 1006
[RefTXNObjectType] => 101
[tmpTXNName] => CN-33
[tmpTXNDate] => 2014-08-26
[RefTXNLineNo] => 0
[tmpOpenAmount] => 0
[tmpOpenAmt] => -500.000
[tmpTXNAmount] => 500
[tmpNarration] => Being amount paid to supplier
[Amount] => 500
[TXNCurrencyID] => 213
[ExchangeRate] => 1.00000
[RevisionNumber] => 1
[tmpRevisionNumber] => 1
[RowState] => 435
[tmpContactID] => 948
[tmpAccountID] => 303
[tmpBranchID] => 156
[TXNLineNo] => 1
)
[1] => Array
(
[TXNID] => 0
[RefTXNID] => 983
[RefTXNObjectType] => 84
[tmpTXNName] => RTY-01
[tmpTXNDate] => 2014-08-26
[RefTXNLineNo] => 1
[tmpOpenAmount] => 0
[tmpOpenAmt] => -1000.000
[tmpTXNAmount] => 1000
[tmpNarration] =>
[Amount] => 1000
[TXNCurrencyID] => 213
[ExchangeRate] => 1.00000
[RevisionNumber] => 1
[tmpRevisionNumber] => 1
[RowState] => 435
[tmpContactID] => 948
[tmpAccountID] => 303
[tmpBranchID] => 156
[TXNLineNo] => 1
)
[2] => Array
(
[TXNID] => 0
[RefTXNID] => 1006
[RefTXNObjectType] => 101
[tmpTXNName] => CN-33
[tmpTXNDate] => 2014-08-26
[RefTXNLineNo] => 0
[tmpOpenAmount] => 0
[tmpOpenAmt] => -500.000
[tmpTXNAmount] => 500
[tmpNarration] => Being amount paid to supplier
[Amount] => 500
[TXNCurrencyID] => 213
[ExchangeRate] => 1.00000
[RevisionNumber] => 1
[tmpRevisionNumber] => 1
[RowState] => 435
[tmpContactID] => 948
[tmpAccountID] => 303
[tmpBranchID] => 156
[TXNLineNo] => 2
)
[3] => Array
(
[TXNID] => 0
[RefTXNID] => 983
[RefTXNObjectType] => 84
[tmpTXNName] => RTY-01
[tmpTXNDate] => 2014-08-26
[RefTXNLineNo] => 1
[tmpOpenAmount] => 0
[tmpOpenAmt] => -1000.000
[tmpTXNAmount] => 1000
[tmpNarration] =>
[Amount] => 1000
[TXNCurrencyID] => 213
[ExchangeRate] => 1.00000
[RevisionNumber] => 1
[tmpRevisionNumber] => 1
[RowState] => 435
[tmpContactID] => 948
[tmpAccountID] => 303
[tmpBranchID] => 156
[TXNLineNo] => 2
)
)
I already use following script to get sum of Amount field
$ret = array_sum(array_map(function ($i) { return $i['Amount']; }, $data));
But this is not working for me. I have to fetch sum of amount TxnLineNo Wise...
Maybe you could use something like this?
$amounts = array();
for($TxnLineNo = 0; $TxnLineNo < 3; $TxnLineNo++) {
$amounts[$TxnLineNo] = array_sum(array_map(function ($i) { global $TxnLineNo; return ($i['TXNLineNo']==$TxnLineNo)?$i['Amount']:0; }, $data));
}
var_dump($amounts);
Or, if you want a specific TxnLineNo, just (e.g. 2):
$ret = array_sum(array_map(function ($i) { return ($i['TXNLineNo']==2)?$i['Amount']:0; }, $data));
As you only want to sum a single thing, you could do a simple loop like this:
$sum = 0;
foreach ($whatever_your_array_is_called as $txtline_arr) {
$sum += $txtline_arr['Amount'];
}
You can try like below
/**
* #param $arr -> Your array
* #param $sum_ind -> which index value you want to sum(eg, Amount)
* #param $check_ind -> checking index (eg, TXNLineNo)
* #param $check_val -> Checking index value (eg,. 1, 2, ....)
* #return int -> Expected summation
*/
function getSumByIndex($arr, $sum_ind, $check_ind, $check_val){
$sum = 0;
foreach($arr as $val){
if($val[$check_ind] == $check_val){
$sum += $val[$sum_ind];
}
}
return $sum;
}

how to extract values from this array

I have this array which I want to extract the values using the extract php function but for some reason it's not working for me.
This is the array:
Array
(
[5] => Array
(
[quantity] => 1
[price] => 45
)
[7] => Array
(
[quantity] => 1
[price] => 18
)
)
and this is the output I would like to see
$pid = 5;
$quantity = 1;
$price = 45;
Why not a simple foreach loop?
$my_array = array(
5 => array(
'quantity' => 1,
'price' => 45.00,
),
7 => array(
'quantity' => 1,
'price' => 18.00,
),
);
foreach($my_array as $pid => $data) {
$pid; // 5, 7
$data['quantity']; // 1, 1
$data['price']; // 45.00, 18.00
}

GET Max array from two array PHP

I want which is the biggest array from following array.
[13] => Array
(
[0] => 1
[1] => 3
[2] => 9
)
[15] => Array
(
[0] => 1
[1] => 5
[2] => 8
)
[33] => Array
(
[0] => 1
[1] => 9
[2] => 13
)
I want a code that would return last array with key 33.
Please Help.
Use max to get the maximum from the keys of your array
$yourarray=array(13 => Array
(
0 => 1,
1 => 3,
2 => 9,
),
15 => Array
(
0 => 1,
1 => 5,
2 => 8,
),
33 => Array
(
0 => 1,
1 => 9,
2 => 13,
));
$arr=max(array_keys($yourarray));
print_r($yourarray[$arr]);
Output:
Array
(
[0] => 1
[1] => 9
[2] => 13
)
This should do the trick...
<?php
$tests = array(
13 => array(1,3,9),
15 => array(1,5,8),
33 => array(1,9,13)
);
$array_totals = array_map('array_sum', $tests);
krsort($array_totals);
$maxArray = each($array_totals);
var_dump($maxArray);
Gives
array (size=4)
1 => int 23
'value' => int 23
0 => int 33
'key' => int 33
Not the most beautiful thing, but readable ;)
$tests = array(
13 => array(1,3,9),
15 => array(1,5,8),
33 => array(1,9,13)
);
$max = -1;
$max_key = -1;
foreach ($tests as $k => $v) {
$cur_max = max($v);
if ($cur_max >= $max) {
$max = $cur_max;
$max_key = $k;
}
}
echo "max: $max; max_key: $max_key";
Gives:
max: 13; max_key: 33
To make it more beautiful: use array_map and sorting.

Categories