Check for all combinations of key values in array? - php

I have this dataset to work with:
Array
(
[John Doe] => Array
(
[137] => 7
[22] => 8
[145] => 7
)
[George] => Array
(
[143] => 2
[18] => 7
)
[Alisa Baumbach] => Array
(
[148] => 7
[145] => 5
)
)
Now I want to see if I have atleast one match between the user arrays between on their keys. I would do this by using array_intersect_key:
$matches = array_intersect_key($user_cor['John Doe'], $user_cor['Alisa Baumbach']);
This works ofcourse but these values are hardcoded, I want to automate this to run all combinations through it. How would I go about checking if:
User 1 data intersects with User 2
User 2 data intersects with User 3
User 1 data intersects with User 3
Ofcourse this is already minified to 3 comparisons instead of 6 since I removed the doubles because I only want unique combinations. How would I go about doing this?
I know this seems fairly typical and all but I have a lot of difficulty with phrasing this let alone searching for answers on how to do this.
Your time would be greatly appreciated in helping me understand this problem.

Something like the following?
$keys = array_keys($user_cor);
for ($i = 0;$i < count($keys);$i++) {
for ($j = $i+1;$j < count($keys);$j++) {
$matches[$i.",".$j] = array_intersect_key($user_cor[$keys[$i]], $user_cor[$keys[$j]])
}
}

Related

Comparing arrays until I have a unique array

I have the following multidimensional array called $existing_combinations
Array
(
[0] => Array
(
[1] => 6
[2] => 7
[3] => 9
)
[1] => Array
(
[1] => 1
[2] => 21
[3] => 9
)
[2] => Array
(
[1] => 1
[2] => 7
[3] => 9
)
)
I then generate a new array ($new_combination) which has a combination of the same set of values. Example:
Array
(
[1] => 6
[2] => 21
[3] => 9
)
I then test if $new_combination exists in $existing_combinations with the following in the hope that I will end with a unique combination in $new_combination:
foreach($existing_combinations as $key => $combination){
while($new_combination == $combination){
$new_combination = generateNewCombination();
}
}
The problem is that if $new_combination matches an array that is not at index 0, then when I generate a new combination I am at risk of this matching a $combination that has already been tested against (and will not be tested again).
Sorry if this is a simple one but I'm struggling to think of how I can ensure $new_combination will always end up unique.
Any ideas?
Thanks
You can use in_array in this case, because php compares arrays as value. So, the code can be:
while(in_array($new_combination = generateNewCombination(), $existing_combinations));
print_r($new_combination);
I wrote the below before realizing that in_array can also see if an array exists within an array. So you can simply do this:
if (!in_array($new_combination, $existing_combinations)) {
// It's unique.
}
In the below outdated bit, see the note on using sort, if a different sequence of the same numbers isn't considered unique for your purposes.
[ For Entertainment ]
May not be the most elegant way around, but I would simply do this to keep it simple:
$combo_hashes = [];
// Implode the existing combos into strings.
foreach($existing as $vals) {
$combo_hashes[] = implode(':', $vals);
}
Then, all you need to check with your new combo is:
// Check if the "hash"-string already exists.
if (!in_array( implode(':', $new_combo), $combo_hashes)) {
// ... and we're unique.
}
This presumes that you consider [1,3,2] different from [2,1,3]. If they are equivalent (I don't know what your use case is), you should sort($vals); before you generate the check-strings.
Merge all the second level arrays and run array_unique() to get rid of the duplicate values.

calculating the average of last values in PHP using Queue

My problem is easy to understand, I need to loop a table and calculate the average of every last 4 value. I try to use Queue to Push the current value and to pop the first value pushed.
I have 2 problem, The Queus works as Stack, when I pop, the last value goes out and not the first one
$q = new SplQueue();
$q->push(1);
$q->push(2);
$q->push(3);
$q->push(4);
$q->push(5);
$q->pop();
I get this Array as ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 ) )
I want this Array as ( [0] => 2 [1] => 3 [2] => 4 [3] => 5 ) )
Second problem, How to use array_sum($q) / $counter[$q]; on Queue ?
Thank you
As it is said in documentation (http://php.net/manual/ro/class.splqueue.php ), if you use push() and pop() it will behave like a stack. Use enqueue() and dequeue()
If you want to get the average of last 4 values, you can create a new array containing the 4 values of your queue dequeue(), then use array_sum($a)/ count($a) on it
If you do not want to create a new array you can simply:
$sum = 0;
$lastElements = 4;
for($i = 0;$i<$lastElements;$i++)
$sum+= $q.dequeue()
echo $sum/$lastElements;
And you can scale this by changing the $lastElements value.The code is not tested

If value exists in one PHP array, add value to second array

I have two PHP arrays. One contains a group name and another contains a pay wage value.
$group_wages_array = Array ( [0] => 1 [1] => 4 [2] => 1 [3] => 3 );
This means there are four employees on the schedule. Two are assigned to group 1, another to group 4 and the last to group 3.
The second array is as follows:
$tot_wages_array = Array ( [0] => 500 [1] => 44 [2] => 80 [3] => 11.25 );
This is a sample array of each employee's wage. Both arrays are constructed in order as values are added in a mysql while loop as it pulls the info from the database.
Later on down the line, I combine the two arrays to get one array where the key is the group number and the value is the total wages for that group:
$combined_group_wages = array_combine($group_wages_array, $tot_wages_array);
This works like a charm EXCEPT for when more than one employee is assigned to the same group. These arrays are built in a mysql while loop as it loops through each employee's info:
array_push($tot_wages_array, $totemp_wages_sch); // Add their wage to the array
array_push($group_wages_array, $emp_data['group_id']); // Add their group to the array
Instead of just pushing the data to the array, I need to do this... I know the english but I don't know how to code it:
If $emp_data['group_id'] exists as value in $group_wages_array, add nothing to this array but get the key. Add $totemp_wages_sch to $tot_wages_array where key = group_wages_array key
I know it sounds more like an SQL query but I have to keep the keys and values in order so that they can be combined later in the page. If I can get this to work right, The arrays shown in the example would be:
$group_wages_array = Array ( [0] => 1 [1] => 4 [2] => 3 );
$tot_wages_array = Array ( [0] => 580 [1] => 44 [2] => 11.25 );
$combined_group_wages = array_combine($group_wages_array, $tot_wages_array);
$combined_group_wages = Array ( [1] => 580 [4] => 44 [3] => 11.25 );
...I've got to make this work using PHP. Any ideas?
I came up with a solution based on a combination of two of the answers submitted below. Here it is if it can help someone:
if(in_array($emp_data['group_id'], $group_wages_array)){
$key = key($group_wages_array);
$tot_wages_array[$key] += $totemp_wages_sch;
} else {
array_push($group_wages_array, $emp_data['group_id']);
array_push($tot_wages_array, $totemp_wages_sch);
}
This should do it:
$group_wages_array = array(1, 4, 1, 3);
$tot_wages_array = array(500, 44, 80, 11.25);
$combined_group_wages = array();
for ($i=0; $i<count($group_wages_array); $i++) {
$group = $group_wages_array[$i];
if (array_key_exists($group_wages_array[$group], $combined_group_wages)) {
$combined_group_wages[$group] += $tot_wages_array[$i];
} else {
$combined_group_wages[$group] = $tot_wages_array[$i];
}
}
print_r($combined_group_wages);
Yields:
Array
(
[1] => 580
[4] => 44
[3] => 11.25
)
But I recommend that you just switch to using objects to better represent your data.
If I could see the entirety of the code that would help a lot, but here's your English converted to php. Show me more code and I can perfect it, until then try this ->
if(in_array($emp_data['group_id'], $group_wages_array)){
$key = key($group_wages_array);
$tot_wages_array[$key] = $totemp_wages_sch;
} else {
array_push($group_wages_array, $emp_data['group_id']);
}

manipulate multiarrays

I am pulling some data from a mysql table via the following:
$result = mysql_query("SELECT characters_ID, name, borndate, deathdate, marrieddate, ispregnant FROM characters WHERE isfemale='1'",$db);
$femaledata = array();
while ($row_user = mysql_fetch_assoc($result))
$femaledata[] = $row_user;
This gives me an array that looks like this:
Array (
[0] => Array ( [characters_ID] => 2 [name] => Helene [borndate] => 35 [deathdate] => 431 [marrieddate] => 157 [ispregnant] => 0 )
[1] => Array ( [characters_ID] => 4 [name] => Isabelle [borndate] => 161 [deathdate] => [marrieddate] => 303 [ispregnant] => 1 )
[2] => Array ( [characters_ID] => 7 [name] => Helene [borndate] => 326 [deathdate] => [marrieddate] => [ispregnant] => 0 )
[3] => Array ( [characters_ID] => 72 [name] => Faylinn [borndate] => 335 [deathdate] => [marrieddate] => [ispregnant] => 0 )
[4] => Array ( [characters_ID] => 74 [name] => Relina [borndate] => 349 [deathdate] => [marrieddate] => [ispregnant] => 0 )
)
Now I need to remove any characters who have a value for deathdate or ispregnant, and then I need to run some code on the others. For instance I need to grab the borndate value, compare it to the current date to find age, and based partly on age, I need to run code for each to determine if the character has become pregnant on the turn.
Apologies that this seems like a long-reaching question. Multidimensional arrays still seem to confound me.
Edit: (question needs to be more clear)
Can you please suggest the best way that I would either explode or break up the array, and then do conditional modification to the data, or instead how I could remove unneeded data and then do conditional modification to the data.
My ultimate output here would be taking suitable female characters (not dead or pregnant already), and based on their age, giving them a chance at becoming pregnant. If true, I'd throw some code back at the SQL database to update that character.
Thanks!
All the things you need could probably get done with SQL :
Now I need to remove any characters who have a value for deathdate or
ispregnant
Simply add some argument to your WHERE condition :
isPregnant IS NULL AND deathdate IS NULL
For instance I need to grab the borndate value, compare it to the
current date to find age
Depending of your field format the maths could be done in SQL , have look to the DATE function of mysql
Don't underestimate the power of your sql server , 99% of the time it is probably faster than php to work on data set.
Instead if immediately removing some rows from your array, try limiting the data you recieve through SQL.
You can loop through your array like this:
foreach($femaledata as $female)
{
echo $female['name'];
}
do you mean something like this?
$femaledata = array();
while ($row_user = mysql_fetch_assoc($result)) {
$ok = false;
// do you validation for every user
if($ok) array_push($femaledata,$row_user);
}
TJHeuvel gave you the right answer, and you should accept that answer. However, to inform: multidimensional arrays need not confound. Let me see if I can explain.
In PHP, you can put any object at all into an array, including other arrays. So, let's say you have an array that contains other arrays. When you iterate over that array using a looping construct (usually a foreach loop), each iteration of the loop will give you another array; if you want to access the elements of this sub-array, just loop over it. This is called a nested loop. Example:
$r = array(
array(1,2,3),
array(4,5,6),
array(7,8,9)
);
foreach ($r as $cur) {
foreach ($cur as $num) {
echo $num;
}
}
In each iteration of the outer loop, $cur contains an array; the inner loop iterates over contents of this array. This technique allows you to process arrays of any dimension.
However, in your specific case, you don't need to use an inner loop to iterate over your subarrays. You only need to access certain elements of your subarrays by their keys, rather that processing all of them in turn. So, a simple foreach loop will do.

Using array_rand to select a top level array and all it's decendents

Hi there I'm a bit confused on how I go about this. Any help would be greatly appreciated.
I have the following code.
$worms_level1 = $this->catch_the_worm_model->get_worms_by_level(1);
$captured_worms = array();
for ($i = 0; $i < $num_worms; $i++)
{
$captured_worms[$i] = array_rand($worms_level1);
}
return $captured_worms;
The $worms_level1 multidimensional array takes the following format:
Array ( [0] => Array ( [worm_id] => 1
[worm_name] => Verm
[worm_description] => The most common verm, not a huge threat but a great nuisance.
[worm_level] => 1
[worm_value] => 1 )
[1] => Array ( [worm_id] => 2
[worm_name] => Vermichav
[worm_description] => Vermichav loves a scuffle. He's been known to spit in Wormcatcher's eyes and inflict pain by cigarette burns.
[worm_level] => 1 [worm_value] => 1 )
)
At the minute the code is successful at selecting random arrays and saving them to a new array eg
Array ( [0] => 1 [1] => 1 )
but I also want the descendent arrays to be saved to the new array.
How about:
$captured_worms=array();
$howmany=20;
do{
$howmany-=count($captured_worms);//decreases $howmany by the number we already grabbed
shuffle($multiarray); //reorder the multiarray randomly
$captured_worms=array_slice($multiarray,0,$howmany);//get as many elements as you want
} while(count($captured_worms)<$howmany); //ensures at least $howmany

Categories