Counting the values of an array with nesting - php

I have the following array, which is a load of arrays nested in a bigger array:
Array
(
[0] => Array
(
[vote_for] => 15
)
[1] => Array
(
[vote_for] => 15
)
[2] => Array
(
[vote_for] => 15
)
[3] => Array
(
[vote_for] => 5
)
[4] => Array
(
[vote_for] => 5
)
[5] => Array
(
[vote_for] => 2
)
[6] => Array
(
[vote_for] => 2
)
[7] => Array
(
[vote_for] => 2
)
[8] => Array
(
[vote_for] => 2
)
[9] => Array
(
[vote_for] => 2
)
[10] => Array
(
[vote_for] => 2
)
[11] => Array
(
[vote_for] => 2
)
[12] => Array
(
[vote_for] => 2
)
[13] => Array
(
[vote_for] => 2
)
[14] => Array
(
[vote_for] => 2
)
)
I want to do the equivalent of array_count_values on this array, such that I get 15 => 3, 5 => 2 and 2 => 10. How do I un-nest the arrays to do this?

You may want to try reforming your array to count:
$count_array = array();
foreach ($arr as $v) {
$count_array[] = $v['vote_for'];
}
// Now get the counts
$the_count = array_count_values($count_array);

I think array map will also work for this
$count_array = array_map(function($item) { return $item['vote_for']; }, $array);
$the_count = array_count_values($count_array);

Related

PHP Merging multiple multidimensional arrays while preserving keys and without overwriting other keys

I'm trying to figure out how to merge multiple multidimensional arrays while preserving the keys and not overwriting.
I've got a script that loops and generates one multidimensional array every time it loops. I need to store all those arrays in one new array.
For example
$Array1 = Array ( [0] => Array ( [5] => 2 ) );
$Array2 = Array ( [0] => Array ( [6] => Array ( [3] => 4 ) ) );
$Array3 = Array ( [1] => 6 );
$Array4 = Array ( [2] => Array ( [5] => Array ( [3] => 8 ) ) );
$Array5 = Array ( [2] => Array ( [5] => Array ( [4] => 10 ) ) );
$Array6 = Array ( [2] => Array ( [5] => Array ( [5] => 12 ) ) );
$Array7 = Array ( [2] => Array ( [6] => Array ( [5] => 14 ) ) );
$Array8 = Array ( [4] => 16 );
$Array9 = Array ( [7] => Array ( [5] => 18 ) )
$Array10 = Array ( [670] => Array ( [5] => Array ( [3] => Array ( [4] => 20 ) ) ) );
$Array11 = Array ( [34] => Array ( [5] => Array ( [3] => Array ( [3] => Array ( [9] => 22 ) ) ) ) );
The number of arrays produced defer and the number of dimensions also defer per array.
I need to add them all and generate an array like:
$ArrayTotal = Array (
[0] => Array (
[5] => 2
[6] => Array (
[3] => 4
)
)
[1] => 6
[2] => Array (
[5] => Array (
[3] => 8
[4] => 10
[5] => 12
)
[6] => Array (
[5] => 14
)
)
[4] => 16
[7] => Array (
[5] => 18
)
[670] => Array (
[5] => Array (
[3] => Array (
[4] => 20
)
)
)
[34] => Array (
[5] => Array (
[3] => Array (
[3] => Array (
[9] => 22
)
)
)
)
)
There are duplicate keys, like $ArrayTotal[2] but all the keys used to acces the value are always different. For example $ArrayTotal[2][5][3] and $ArrayTotal[2][5][4] share the first key, but the keys used to get to the value are different.
I've tried using array_merge and array_merge_recursive and even just adding them using +. I've also tried:
$out = array();
foreach ($ArrayTotal as $key => $value){
$out[] = array_merge((array)$ArrayN[$key], (array)$value);
}
$ArrayTotal = $out;
Where I looped though all the $ArrayNs that where generated. But it overwrites duplicate keys in the first dimension. So it will for example not store $Array4, $Array5 and $Array6.
Another small but important detail is, that the keys can be strings.
Like:
$ArrayX = Array ( ["SomeKey"] => Array ( [5] => Array ( ["OtherKey"] => "TheValue" ) ) );
My question is:
How can I generate the $ArrayTotal as described?
I would prefer something that I can implement in the loop and that adds the arrays one by one.
Thanks

Explode each values of Array element

I have an array like :
Array
(
[2] => 2,6
[3] => 1
[4] => 14
[5] => 10
[6] => 8
)
I want to explode each element of an array and return a new array using array_map, so that I can avoid using loop, and creating extra function to call back.
O/p should be like :
Array
(
[2] => Array
(
[0] => 2
[1] => 6
)
[3] => Array
(
[0] => 1
)
[4] => Array
(
[0] => 14
)
[5] => Array
(
[0] => 10
)
[6] => Array
(
[0] => 8
)
)
You can use
$result = array_map(function($val) {
return explode(',', $val);
}, $input);
Which will result in
Array
(
[2] => Array
(
[0] => 2
[1] => 6
)
[3] => Array
(
[0] => 1
)
[4] => Array
(
[0] => 14
)
[5] => Array
(
[0] => 10
)
[6] => Array
(
[0] => 8
)
)
This will work on PHP >= 5.3 with support for anonymous functions.
You can also do
$result = array_map('str_getcsv', $input);
This will also result in
Array
(
[2] => Array
(
[0] => 2
[1] => 6
)
[3] => Array
(
[0] => 1
)
[4] => Array
(
[0] => 14
)
[5] => Array
(
[0] => 10
)
[6] => Array
(
[0] => 8
)
)
Try following code
$newArr = array_map(function($val, $key){
return explode(",", $val);
}, $arr);
$data = array(2 => '2,6',3 => '1',4 => '14',5 => '10',6 => '8');
foreach($data as $key => $val) {
$new = explode(',',$val);
$data[$key] = $new;
}
$output = $data;
echo '<pre>';
print_r($output);

Sort multimedinsional array with dynamic key name

I want to sort a php array whose key value combination is dynamic thus making it difficult to define a function and apply usort()
Here is the array
Array (
[0] => Array ( [PAYE] => 43 )
[1] => Array ( [VAT] => 2 )
[2] => Array ( [NHIF] => 1 )
[3] => Array ( [NSSF] => 2 )
[4] => Array ( [MPESA] => 1 )
[5] => Array ( [EQUITEL] => 1 )
[6] => Array ( [AIRTEL] => 1 )
[7] => Array ( [CER] => 2 )
[8] => Array ( [BDD] => 4 )
[9] => Array ( [BMI] => 1 )
[10] => Array ( [TG] => 7 )
[11] => Array ( [BT] => 3 )
[12] => Array ( [EPL] => 4 )
[13] => Array ( [KPL] => 8 )
)
I want to sort the array using the right most value. The result should be
Array (
[0] => Array ( [PAYE] => 43 )
[13] => Array ( [KPL] => 8 )
[10] => Array ( [TG] => 7 )
[8] => Array ( [BDD] => 4 )
[12] => Array ( [EPL] => 4 )
[11] => Array ( [BT] => 3 )
[7] => Array ( [CER] => 2 )
[3] => Array ( [NSSF] => 2 )
[1] => Array ( [VAT] => 2 )
[3] => Array ( [NSSF] => 2 )
[6] => Array ( [AIRTEL] => 1 )
[9] => Array ( [BMI] => 1 )
[4] => Array ( [MPESA] => 1 )
[2] => Array ( [NHIF] => 1 )
)
How should I go about it?
use uasort function to save keys and array_shift to take values to compare
uasort($array, function($i1, $i2) {
return array_shift($i2) - array_shift($i1); });
print_r($array);
uasort and current functions will do the job:
// $arr is your initial array
uasort($arr, function($a, $b){ // will maintain index association
return current($b) - current($a);
});
http://php.net/manual/en/function.current.php

Compare values of two multidimentional array and insert if not exits

I have two array $array1 and $array2 which I get dynamically and look like
$array1 = Array
(
[0] => Array
(
[hour] => 10
[activity] => Array
(
[0] => Array
(
[activity_id] => 1
[cnt] => 2
)
[1] => Array
(
[activity_id] => 2
[cnt] => 1
)
)
)
[1] => Array
(
[hour] => 11
[activity] => Array
(
)
)
[2] => Array
(
[hour] => 12
[percentage] => 0
[activity] => Array
(
[0] => Array
(
[activity_id] => 2
[cnt] => 5
)
[1] => Array
(
[activity_id] => 3
[cnt] => 2
)
)
)
);
$array2 = Array
(
[0] => Array
(
[id] => 1
[name] => Phone Calls
[readable] => 1
[status] => active
)
[1] => Array
(
[id] => 2
[name] => Meeting With Customer
[readable] => 1
[status] => active
)
[2] => Array
(
[id] => 3
[name] => Others Works
[readable] => 1
[status] => active
)
);
which i need to compare.
if $array2['id'] is not in $array1["activity"](i.e"activity_id") add array ['activity_id'=>$array2['id'],'cnt'=>0] to $array1['activity'].
My result must be like
$result = Array
(
[0] => Array
(
[hour] => 10
[activity] => Array
(
[0] => Array
(
[activity_id] => 1
[cnt] => 2
)
[1] => Array
(
[activity_id] => 2
[cnt] => 1
)
[2] => Array
(
[activity_id] => 3
[cnt] => 0
)
)
)
[1] => Array
(
[hour] => 11
[activity] => Array
(
[0] => Array
(
[activity_id] => 1
[cnt] => 0
)
[1] => Array
(
[activity_id] => 2
[cnt] => 0
)
[2] => Array
(
[activity_id] => 3
[cnt] => 0
)
)
)
[2] => Array
(
[hour] => 12
[percentage] => 0
[activity] => Array
(
[0] => Array
(
[activity_id] => 1
[cnt] => 0
)
[1] => Array
(
[activity_id] => 2
[cnt] => 5
)
[2] => Array
(
[activity_id] => 3
[cnt] => 2
)
)
)
);
What i have tried is
$finalArray = array();
foreach($array1 as $arr1) {
foreach($array2 as $arr2) {
if(!in_array($arr2['id'], $arr1['activity'])) {
$array = ['activity_id'=>$arr2['id'], 'cnt'=>0];
}
array_push($arr1['activity'], $array);
unset($array);
}
array_push($finalArray, $result);
}
print_r($finalArray);
in_array() function is not working as I excepted or I am trying to do it in the wrong way. Can someone helps me with this?
Sorry,finally i get what i did wrong.May be someone get helped.
everything is ok just change the line
if(!in_array($arr2['id'], $arr1['activity'])) {
into
if(!in_array( $readActivity['id'], array_column($result['activity'],'activity_id'))){

How to split multiple values of keys into separate keys in an Array?

I have this Array
Array (
[0] => Array (
[0] => Array ( [value] => Cooking, [occurence] => 1 )
[1] => Array ( [value] => Music, [occurence] => 1 )
[2] => Array ( [value] => Football,Cooking, [occurence] => 1 )
[3] => Array ( [value] => Travel, [occurence] => 1 )
[4] => Array ( [value] => Cooking,Reading, [occurence] => 2 )
[5] => Array ( [value] => Football,Travel, [occurence] => 1 )
[6] => Array ( [value] => Football, [occurence] => 1 )
[7] => Array ( [value] => Music,Cooking, [occurence] => 1 )
[8] => Array ( [value] => Reading,Travel, [occurence] => 1 )
)
)
The [2], [4], [5], [7] and [8] have 2 values for the key [value].
What I want to do is to split the 2 values of these keys in different keys.
The new values should not go to new Arrays, but they will be added to the similar existing Arrays.
For example, if I break the [2] (Football,Cooking) the result will be that the occurence of [6] (Football) will be incremented by 1 and the [occurence] of [0] (Cooking) will be incremented by 1 also.
Thank you !
Yann
$newdata = array()
foreach($array as $data) { // $array being the inner array with the 9 elements
$keys = explode(',', $data['value']);
foreach ($keys as $subkey) {
$newdata[$subkey]++;
}
}
which would give you something like
$newdata = array(
'Cooking' => 4,
'Football' => 3
etc...
);
Not sure how you want your structure to look afterwards, but at least this'll do the inventory for you.

Categories