Combine arrays, count values and total in PHP - php

After many attempts to crack this I am stuck so I turn to SO for help.
I have two arrays, as below. The keys from both arrays are relational to each other.
I need to combine both arrays together as a key=>value pair.
for example:
[Internet Explorer] => 3
[Internet Explorer] => 2
However, following this I need to total the values of the duplicate keys. Resulting in a unique total key=>value pair for each browser.
for example:
[Internet Explorer] => 5
[Google Chrome] => 3
Thank you for looking, I have tried many array functions and I always come to the same result of getting unique keys without totalised values.
Array
(
[0] => Unknown
[1] => Unknown
[2] => Unknown
[3] => Internet Explorer
[4] => Internet Explorer
[5] => Mozilla Firefox
[6] => Internet Explorer
[7] => Unknown
[8] => Unknown
[9] => Google Chrome
[10] => Google Chrome
[11] => Mozilla Firefox
[12] => Mozilla Firefox
[13] => Unknown
)
Array
(
[0] => 1
[1] => 2
[2] => 1
[3] => 1
[4] => 1
[5] => 1
[6] => 1
[7] => 1
[8] => 1
[9] => 1
[10] => 1
[11] => 1
[12] => 2
[13] => 1
)
Edit: Adding code for clarity.
$agent_list is the result of a query which collects unique instances of USER AGENT and counts them.
The getBrowser function searches each $agents and extracts the browser type.
$agents = array();
$agents_count = array();
foreach($agent_list as $value1)
{
$agent = getBrowser($value1['agent']);
array_push($agents,$agent);
array_push($agents_count,(int)$value1['count']);
}

Assuming the keys array is $keys and the values array is $values, this should work.
$result = array_fill_keys(array_unique($keys), 0);
foreach($keys as $i=>$k){
$result[$k] += $values[$i];
}
Demo: http://ideone.com/9EIOU

Why not iterate over one array and add values if they exists or append if they don't exist:
foreach($array1 as $key => $value){
$array2[$key] += $value;
}
This will ad the value or add the key with the value if it doesn't exist in $array2.

Hope, I understand your question
Let $a,$b are input arrays, result will be in $a
foreach($b as $k=>$v){
if(isset($a[$k]))
$a[$k]+=$v;
else
$a[$k]=$v;
}

Related

Compare Array elements and add based on key and value

I have two arrays like this:
$array_1 = Array ( [0] => 4 [1] => 6 [2] => 2 [3] => 6 [4] => 4 [5] => 10 [6] => 4 [7] => 6 [8] => 2 [9] => 2 [10] => 4 [11] => 4 [12] => 2 [13] => 2 );
$array_2 = Array ( [0] => DK [1] => GA [2] => DK [3] => GA [4] => DK [5] => GA [6] => WE [7] => VE [8] => WE [9] => VE [10] => PLA [11] => PRA [12] => PLA [13] => PRA ) ;
Now I want result like this:
$dk=4+2+4=10;
$ga=6+6+10=22;
$we=4+2=6;
$ve=6+2=8;
$pla=4+2=6;
$pra=4+2;
Explanation:
In $array_2, 'DK' exists 3 times and key values are = 0,2 and 4.
So, i have to add the values of $array_1 having key 0,2,4 and assign them to $dk. Here, $dk will be 4+2+4=10. This process will be same for all other variables.
How can i do this??
Instead separate variable name I suggest you to make array like this
<?php
$array_1 = [4,6,2,6];
$array_2 = [ 0=> "DK", 1=>"GA", 2=>"DK", 3=>"GA"];
$newArray = [];
foreach($array_2 as $key=>$value){
if(isset($newArray[$value])){
$newArray[$value] +=$array_1[$key];
}else{
$newArray[$value] =$array_1[$key];
}
}
print_r($newArray);
?>
Live Demo
Output :
Array
(
[DK] => 6
[GA] => 12
)
Another suggestion : Instead complex programming try to make good relation or binding to not get any inconsistency in records
This will loop array2 and build an array with the sum.
Then output it (just to see the result), then I use extract to pull out the variables as you want them.
But I would rather keep them in the array
Foreach($array_2 as $key => $val){
If(!isset($new[$val])) $new[$val] =0;
$new[$val] += $array_1[$key];
}
Var_dump($new);
Extract($new);
https://3v4l.org/jOR7Z

Get subset of array based on values in PHP

I have an array like the below one
Array
(
[0] => 1
[1] => 1
[2] => 1
[3] => 2
[4] => 2
[5] => 3
[6] => 3
[7] => 3
[8] => 4
[9] => 4
[10] => 4
)
Is there any way to get a subset of this array using the values? So that, if need the subset of value 1, then it has to display
Array
(
[0] => 1
[1] => 1
[2] => 1
)
And if subset of 2 then
Array
(
[3] => 2
[4] => 2
)
And so on.. I need to preserve the index too.
I searched so many places. But didn't get an answer for this. I wish to avoid the multiple looping for this.
You can use array_filter to filter an array down to only the elements you're looking for. Set $subset to whatever value you're searching for, and it'll return the matching elements, without changing the keys.
$subset = 2;
$results = array_filter($array, function ($item) use ($subset) {
return $item === $subset;
});
print_r($results);
Array
(
[3] => 2
[4] => 2
)
See https://eval.in/926983
Try array_chunk
array_chunk($array,4,true);
First parameter array
Second parameter size
Third parameter preserve keys

PHP Working with an array to find ranges and missing numbers

I have an array that looks like this:
[0] => Array
(
[1] => 5
[2] => 4
[3] => 3
[5] => 1
[7] => 1
[8] => 2
[9] => 3
[10] => 4
[11] => 5
)
[1] => Array
(
[1] => 6
[2] => 5
[4] => 3
[5] => 2
[6] => 1
[8] => 3
[9] => 4
[10] => 5
[11] => 6
)
[2] => Array
(
[1] => 7
[2] => 6
[3] => 5
[4] => 4
[5] => 3
[6] => 2
[7] => 3
[8] => 4
[11] => 7
)
I have an order of operations I'm trying to go through and I really don't know where to go from here. Any suggestions would be of great help.
First I give my class the number of items I want to return. For example here we'll use 4.
I want to loop through and find the item in the array that has the lowest value.
I want to look at the keys to the items around (it included) and be sure they're not missing a number if they are..reject it..
In this example the first one you would come to would be:
[5] => 1
Now looking around it you see that the keys are missing some numbers. So no combination of 4 will get that to match any 4 in the proper order.
[1] => 5
[2] => 4
[3] => 3
[5] => 1 //this one
[7] => 1
[8] => 2
[9] => 3
In this situation I want it to move onto the next case.
[7] => 1
Notice this one will work due to the keys being 7,8,9,10.
[7] => 1
[8] => 2
[9] => 3
[10] => 4
This is what I would like returned first..but I don't even know how to begin to get there.
Further more there are situations like this..Say for example there are no 1's at all in the dataset..and only this lone 2 in the last one.
[0] => Array
(
[1] => 5
[2] => 4
[3] => 3
[5] => 3
[7] => 3
[8] => 3
[9] => 3
[10] => 4
[11] => 5
)
[1] => Array
(
[1] => 6
[2] => 5
[4] => 3
[5] => 3
[6] => 3
[8] => 3
[9] => 4
[10] => 5
[11] => 6
)
[2] => Array
(
[1] => 7
[2] => 6
[5] => 3
[6] => 2 // this one
[7] => 3
[8] => 4
[11] => 7
)
The following wont work:
[6] => 2 // this one
[7] => 3
[8] => 4
[11] => 7
but this one will:
[5] => 3
[6] => 2 // this one
[7] => 3
[8] => 4
I have no idea on how to approach this.. If someone could offer some advice it would be GREATLY appreciated. Thanks so much in advance.
The following assumes your data is in an array called $data. I'll describe it in steps, then pull it all together as a function.
Step 1 find the min value:
$minValue=min($data);
Step 2 loop through the array looking for all values that are that value:
foreach($data as $index => $value){
if($value == $minValue){
// $index is a candidate!
}
}
Step 3 Check if $valuesToReturn entries exist after index:
$success=true;
for($i=1;$i<=$valuesToReturn;$i++){
if(!array_key_exists($index + $i,$data)){
// Candidate failed.
$success=false;
break;
}
}
Step 4 If the candidate was successful, return it.
if($success){
return $index;
}
Putting that all together, we get this:
function findSuitableIndex($data,$valuesToReturn){
// Min:
$minValue=min($data);
foreach($data as $index => $value){
if($value == $minValue){
// $index is a candidate!
// test if index is actually suitable:
$success=true;
for($i=1;$i<=$valuesToReturn;$i++){
if(!array_key_exists($index + $i,$data)){
// Candidate failed.
$success=false;
break;
}
}
if($success){
return $index;
}
}
}
// If we fell down here, we failed to find any successful results.
return -1;
}
Working sample:
Code on eval.in
Here are some suggestions. Your exact implementation would depend on your particular situation.
To loop through each element in the array, you could use a foreach loop.
foreach ($arr[0] as $index => $value) {
// Here, $arr[0][$index] == $value;
}
To check if a key exists or not, you could use array_key_exists.
if ( !array_key_exists($index - 1, $arr[0]) ) {
// The previous index is missing in the array.
}
A simple (but inefficient) way to find a contiguous sequence of k indices with the smallest value at the first index would be to find the smallest element and check if the contiguous sequence exists; if not, find the next smallest element and recursively check until you have completed processing the largest element.
You could also try finding all contiguous sequences of at least length k and then selecting the sequence with the smallest value at the first index.
Hope this helps!

php mapping keys to multidimensional array

Quite new to php. I would be grateful is anyone can provide guidance about mapping the values in this array using php this is the output from var_dump
array(3) {
["k"]=>
string(78) "method,from_tag,to_tag,callid,sip_code,sip_reason,time,from_user,to_user,token"
["v"]=>
string(326) "BYE,gFNk8BZBg,B2B.269.327,KjmE8oPOV1,200,OK,Wed May 28 23:11:43 2014
,patientdemo1.gmail,sip:join.me#192.168.1.20:5060;transport=udp,037d30d7239a0a16a658474822c3c9acf7995ac781a9c1c8b4b1a7361f24400d71216209c18eff8b8b0400bb55890bb2a78eb3064b603e6ac4e270b76c36be0e365bf096e426cfb6621aac13fdec54e7bbce74b3d63244b4cb622b16e27da1c4"
["query_type"]=>
string(6) "insert"
}
as you may have noticed the column keys are within first array with key "k" and the values are under "v"
I need to pull some of these values out by referencing the keys within "k"
As stated in the comment. You'd use explode() to set your keys and values into their arrays respectively.
Done so as below:
<?php
$things = array(
'k' => 'method,from_tag,to_tag,callid,sip_code,sip_reason,time,from_user,to_user,token',
'v' => 'BYE,gFNk8BZBg,B2B.269.327,KjmE8oPOV1,200,OK,Wed May 28 23:11:43 2014
,patientdemo1.gmail,sip:join.me#192.168.1.20:5060;transport=udp,037d30d7239a0a16a658474822c3c9acf7995ac781a9c1c8b4b1a7361f24400d71216209c18eff8b8b0400bb55890bb2a78eb3064b603e6ac4e270b76c36be0e365bf096e426cfb6621aac13fdec54e7bbce74b3d63244b4cb622b16e27da1c4'
);
$keys = explode(',', $things['k']);
$values = explode(',', $things['v']);
?>
Which returns:
Keys
Array
(
[0] => method
[1] => from_tag
[2] => to_tag
[3] => callid
[4] => sip_code
[5] => sip_reason
[6] => time
[7] => from_user
[8] => to_user
[9] => token
)
Values
Array
(
[0] => BYE
[1] => gFNk8BZBg
[2] => B2B.269.327
[3] => KjmE8oPOV1
[4] => 200
[5] => OK
[6] => Wed May 28 23:11:43 2014
[7] => patientdemo1.gmail
[8] => sip:join.me#192.168.1.20:5060;transport=udp
[9] => 037d30d7239a0a16a658474822c3c9acf7995ac781a9c1c8b4b1a7361f24400d71216209c18eff8b8b0400bb55890bb2a78eb3064b603e6ac4e270b76c36be0e365bf096e426cfb6621aac13fdec54e7bbce74b3d63244b4cb622b16e27da1c4
)
And now you just need to loop through the values like so using foreach():
$data = array();
foreach($keys as $i => $key) {
$data[$key] = $values[$i];
}
Which would product your final output of:
Array
(
[method] => BYE
[from_tag] => gFNk8BZBg
[to_tag] => B2B.269.327
[callid] => KjmE8oPOV1
[sip_code] => 200
[sip_reason] => OK
[time] => Wed May 28 23:11:43 2014
[from_user] => patientdemo1.gmail
[to_user] => sip:join.me#192.168.1.20:5060;transport=udp
[token] => 037d30d7239a0a16a658474822c3c9acf7995ac781a9c1c8b4b1a7361f24400d71216209c18eff8b8b0400bb55890bb2a78eb3064b603e6ac4e270b76c36be0e365bf096e426cfb6621aac13fdec54e7bbce74b3d63244b4cb622b16e27da1c4
)
Working Example
Footnotes
This probably isn't the most efficient way to handle/do what you want to do. You should rethink how the first array with the columns/values is created and restructure that to suit your needs.
You should use array_combine() instead!
If this answers your question, just click on the arrow to the left there until it is green :) to mark this question as answered!

Re-order PHP array by middle key as start (Circular Sorting)

very basic question however I have had some trouble finding the answers on PHP.NET.
I have the following array:
Array (
[1] => Array
(
[1] => 4
[2] => 1
[3] => 5
[4] => 3
)
[2] => Array
(
[5] => 2
[6] => 8
[7] => 7
[8] => 6
)
[3] => Array
(
[9] => 10
[10] => 9
[11] => 12
[12] => 11
)
[4] => Array
(
[13] => 15
[14] => 16
[15] => 14
[16] => 13
)
)
I want the array to be re-ordered so that the key number 3 in the first series of the array becomes the first, then the rest to be re-ordered from there to eventually get the result of:
Array (
[3] => Array
(
[9] => 10
[10] => 9
[11] => 12
[12] => 11
)
[4] => Array
(
[13] => 15
[14] => 16
[15] => 14
[16] => 13
)
[1] => Array
(
[1] => 4
[2] => 1
[3] => 5
[4] => 3
)
[2] => Array
(
[5] => 2
[6] => 8
[7] => 7
[8] => 6
)
)
I am looking for a way to do this so I can define the array, then the first level key I need to sort by, and then it will return the array in this way.
The standard PHP keys didn't seem to offer something like this, so it would be good to be able to have a separate function such as $newArray = reorder_array($array, $key);
I don't require any sorting of the second level, only the initial 4 main / first level array sections.
You help is greatly appreciated as I have been sitting on this one for awhile without a clear and simple solution.
You re-ordering can be simply implemented with one foreach loop, like:
function reorderArray($array, $key)
{
$found = false;
foreach($array as $k=>$v)
{
$found = $found || $k===$key;
if(!$found)
{
unset($array[$k]);
$array[$k] = $v;
}
//else break can be added for performance issues
}
return $array;
}
with usage
$array=[1=>'foo', 4=>'bar', 9=>'baz', 'test'=>51];
var_dump(reorderArray($array, 9));
var_dump(reorderArray($array, 'test'));
var_dump(reorderArray($array, 'no_such_key'));//original array in result
-check this demo. If keys are consecutive numerics, however, this can be easily implemented with array_slice() calls.

Categories