Check associative array key exists in another array - php

I have two associative array, and
I am trying to find the keys of the first array if they are present in second array.
<?php
$team_member = ["Person_1" => 0, "Person_2" => 0, "Person_3" => 0, "Person_4" => 0];
$today_active_member = ["Person_1" => 0, "Person_3" => 0, "Person_4" => 0];
$i = count($team_member);
while($i--){ //4, 3, 2, 1, false
if(in_array(key($team_member), $today_active_member)) { // check is key available in second array?
echo key($team_member) . " is present today.<br/>";
next($team_member); // goes to the next key
// code goes here
} else {
echo key($team_member) . " isn't present today.<br/>";
next($team_member); // goes to the next key
}
}
But above code is not giving the correct output. now the output is:
Person_1 is present today.
Person_2 is present today.
Person_3 is present today.
Person_4 is present today.
It should output:
Person_1 is present today.
Person_2 isn't present today.
Person_3 is present today.
Person_4 is present today.
How can I find those keys of first array which are in second array.
I've also tried to solve the problem with array_keys(), array_search() but it doesn't work

Instead, you should use the array_key_exists() function, which takes two arguments: the key you want to check for and the array you want to check in.
<?php
$team_member = ["Person_1" => 0, "Person_2" => 0, "Person_3" => 0, "Person_4" => 0];
$today_active_member = ["Person_1" => 0, "Person_3" => 0, "Person_4" => 0];
$i = count($team_member);
while($i--){
if(in_array(key($team_member), array_keys($today_active_member))) {
echo key($team_member) . " is present today.<br/>";
next($team_member);
} else {
echo key($team_member) . " isn't present today.<br/>";
next($team_member);
}
}
PHP online : https://onlinephp.io/c/48b7c

There is a far simpler way using a foreach loop and array_key_exists()
$team_member = ["Person_1" => 0, "Person_2" => 0, "Person_3" => 0, "Person_4" => 0];
$today_active_member = ["Person_1" => 0, "Person_3" => 0, "Person_4" => 0];
foreach( $team_member as $key=>$val){
if (array_key_exists($key, $today_active_member)){
echo $key . " is present today.<br/>";
} else {
echo $key . " isn't present today.<br/>";
}
}
RESULT
Person_1 is present today.<br/>
Person_2 isn't present today.<br/>
Person_3 is present today.<br/>
Person_4 is present today.<br/>

Related

php Optimize multiarray search

I am reading in a file with thousands of lines. I grab the id from each line and check to see if it is in a multiarray, that also has thousands of entries. If it is in the multiarray I need to have the key of the array it is in. I have this all working with the code shown below but it takes a very long time. I'm hoping someone can suggest a way to do it faster?
$array = [['id' => 'A202977', '550' => 0, '710' => 0],
['id' => 'A202978', '550' => 0, '710' => 0],
['id' => 'A202979', '550' => 0, '710' => 0]
];
$found = InMultiArray('A202978', $array);
$key = MultiArraySearch('A202978', $array);
echo 'Found '.$found .' at '.$key.'<br>';
//shows Found 1 at 1
function InMultiArray($needle, $haystack, $strict = false) {
foreach ($haystack as $item) {
if (($strict ? $item === $needle : $item == $needle) || (is_array($item) && InMultiArray($needle, $item, $strict))) {
return true;
}
}
return false;
}
function MultiArraySearch($needle, $haystack) {
foreach ($haystack as $key => $item) {
if (($needle == $item['id'])) {
return $key;
}
}
return FALSE;
}
You can safely and soundly cache the resulting resources into a JSON file, so next time when you need to load the data, you can just grab the content of the JSON file and pass it as a parameter to json_decode.
So, this is how you could proceed:
if the cached file does not exist or it is old, or it is older than the input file
proceed in the old and slow way
pass the result to json_encode and save it into a cache file
else
load the cache file's content
pass it as a parameter to json_decode and you have your result
Alternatively, you can use a database or even a cache-system, like Redis.
If you really need to find the index of the row by the ID field, you can create an associative array of IDs to array indices.
$array = [['id' => 'A202977', '550' => 0, '710' => 0],
['id' => 'A202978', '550' => 0, '710' => 0],
['id' => 'A202979', '550' => 0, '710' => 0]
];
// Array to map ID to array index in $dataRaw
$idIndexMap = [];
// Populate structs
foreach ($array as $i=>$currRow)
{
$idIndexMap[$currRow['id']] = $i;
}
$found = array_key_exists('A202978', $idIndexMap);
$key = $idIndexMap['A202978'];
echo 'Found ' . $found . ' at ' . $key . '<br>';
//shows Found 1 at 1
However if you just need to find the actual row by the ID, it's probably easier to just create an associative array that maps the ID to the actual row.
<?php
$array = [['id' => 'A202977', '550' => 0, '710' => 0],
['id' => 'A202978', '550' => 0, '710' => 0],
['id' => 'A202979', '550' => 0, '710' => 0]
];
// Array to map ID to array index in $dataRaw
$map = [];
// Populate structs
foreach ($array as $currRow)
{
$map[$currRow['id']] = $currRow;
}
$found = array_key_exists('A202978', $map);
$row = $map['A202978'];
echo 'Found ' . json_encode($row) . '<br>';

Array being populated when meeting certain condition

I'm currently trying to have an associative array take values if another array is "full". There are two asso arrays which represent parking lots (one for small cars and the other for larger cars) the small cars can park in the larger spots if theirs are all occupied. I got this to work but i'm stuck on one bit of logic which i don't seem to get.
The small array exists of 10 spots and the large one 14.
The bit that causes me trouble is ( $_SESSION['parkingLarge']["spot1"] === 0 && $_SESSION['parkingSmall']["spot10"] === 1)
I understand that this is to be expected because when it breaks out of the first foreach loop it will fullfill the condition in the next statement and add the last 1 to spot10 in the first array and automatically it will also add it in the 1st spot of the larger array.
Is there a way i could stop this behavior , or code this in a better way ?
Arrays are :
$parkingSmall = array(
"spot1" => 1, "spot2" => 1, "spot3" => 1, "spot4" => 1, "spot5" => 1,
"spot6" => 1, "spot7" => 1, "spot8" => 1, "spot9" => 0, "spot10" => 0
);
$parkingLarge = array(
"spot1" => 0, "spot2" => 0, "spot3" => 0, "spot4" => 0, "spot5" => 0,
"spot6" => 0, "spot7" => 0, "spot8" => 0, "spot9" => 0, "spot10" => 0,
"spot11" => 0, "spot12" => 0, "spot13" => 0, "spot14" => 0
);
$_SESSION['parkingSmall'] = $parkingSmall;
$_SESSION['parkingLarge'] = $parkingLarge;
code
if ($_POST["size"] == 'small') {
foreach ($_SESSION['parkingSmall'] as $key => $value) {
if ($value === 0) {
$_SESSION['parkingSmall'][$key] = 1;
echo "Car parked";
break;
}
}
if ( $_SESSION['parkingLarge']["spot1"] === 0 && $_SESSION['parkingSmall']["spot10"] === 1) {
foreach ($_SESSION['parkingLarge'] as $key => $value) {
if ($value === 0) {
$_SESSION['parkingLarge'][$key] = 1;
echo "Small car parked in large spot";
break;
}
}
}
if ($_SESSION['parkingLarge']["spot14"] === 1) {
echo "No more spaces available in both parkings";
return false;
}
}
Any help on this is more than welcome !!!
You could use array_search for this case, e.g:
$type = 'small';
$key = array_search(0, $_SESSION['parkingSmall']) ?: null;
if (!$key) {
$type = 'large';
$key = array_search(0, $_SESSION['parkingLarge']) ?: null;
}
var_dump($type, $key);

How to compare 2 array with same key but different value PHP

I want to ask about compare 2 arrays with same key but different value.
I have 1 array master (arrayMaster) and 2 or more array data (arrayData1, arrayData2, and maybe could be more). These array data key will have exactly one of arrayMaster data key (I've done for this thing). For data example that I get:
arrayMaster = Array( [apple] => 1 [banana] => 2 [choco] => 1 [donut] => 2 [egg] => 1 )
arrayData1 = Array( [apple] => 8 [banana] => 2 [choco] => 1 )
arrayData2 = Array( [donut] => 5 [choco] => 2 [egg] => 3 )
(We can see that arrayData1 and arrayData2 contain a key from arrayMaster key.)
These arrays I want to compare and give a calculating method. If the array key at arrayData(n) found at arrayMaster, it will do a calculating data, let said it will sum each other.
So, the result is:
arrayResult1 = 1+8 (apple have 1 from master, apple have 8 from arrayData1), 2+2, 1+1
arrayResult2 = 2+5 (donut have 2 from master, donut have 5 from arrayData2), 1+2, 1+3
So I will have 2 new array (or more, depend on how much arrayData) that contain:
arrayResult1 = ([apple] => 9 [banana] => 4 [choco] => 2);
arrayResult2 = ([donut] => 7 [choco] => 3, [egg] => 4);
Anyone know how to do this? I’”ve tried array_intersect but it didn’t work.
Do something like this:
function doCalc($master, $slave) {
$results = array();
foreach( $slave as $key => $value ) {
if( !isset($master[$key]) ) {
$results[$key] = $value;
}
else {
$results[$key] = $master[$key] + $value;
}
}
return $results;
}
$arrayResult1 = doCalc($arrayMaster, $arrayData1);
$arrayResult2 = doCalc($arrayMaster, $arrayData2);
You can write something simpler like this..
function modifyArr(&$arr,$basearray) //<=-- See I am passing & (reference) so your original array will be modified
{
foreach($arr as $k=>$v)
{
if(array_search($k,$basearray)!==null)
{
$arr[$k]=$basearray[$k]+$arr[$k];
}
}
}
modifyArr($arrayData1,$arrayMaster); //<=-- Pass your 1st array
modifyArr($arrayData2,$arrayMaster); //<=-- Pass your 2nd array
Demonstration
Using these as examples:
arrayResult1 = 1+8 (apple have 1 from master, apple have 8 from arrayData1), 2+2, 1+1
arrayResult2 = 2+5 (donut have 2 from master, donut have 5 from arrayData2), 1+2, 1+3
Why not just do this:
// The main arrays for master & data values.
$arrayMaster = array('apple' => 1, 'banana' => 2, 'choco' => 1, 'donut' => 2, 'egg' => 1);
$arrayData1 = array('apple' => 8, 'banana' => 2, 'choco' => 1);
$arrayData2 = array('donut' => 5, 'choco' => 2, 'egg' => 3);
// Set a values to check array.
$values_to_check = array('apple', 'donut');
// Init the results array.
$results_array = array();
// Roll through the values to check.
foreach ($values_to_check as $value) {
// Check if the array key exists in '$arrayMaster'.
if (array_key_exists($value, $arrayMaster)) {
// If it exists, add it to the '$results_array'.
$results_array[$value][] = $arrayMaster[$value];
// Check if the array key exists in '$arrayData1'.
if (array_key_exists($value, $arrayData1)) {
// If it exists, add it to the '$results_array'.
$results_array[$value][] = $arrayData1[$value];
}
// Check if the array key exists in '$arrayData2'.
if (array_key_exists($value, $arrayData2)) {
// If it exists, add it to the '$results_array'.
$results_array[$value][] = $arrayData2[$value];
}
}
}
// Roll through the results array and use 'array_sum' to get a sum of values.
foreach ($results_array as $results_key => $results_value) {
echo $results_key . ' : ' . array_sum($results_value) . '<br />';
}
But looking at your example, I am unclear on why you have separate arrays for $arrayData1 and $arrayData2 so here is the same code, but refactored to have nested arrays in $arrayData which should be more efficient:
// The main arrays for master & data values.
$arrayMaster = array('apple' => 1, 'banana' => 2, 'choco' => 1, 'donut' => 2, 'egg' => 1);
$arrayData = array();
$arrayData[] = array('apple' => 8, 'banana' => 2, 'choco' => 1);
$arrayData[] = array('donut' => 5, 'choco' => 2, 'egg' => 3);
// Set a values to check array.
$values_to_check = array('apple', 'donut');
// Init the results array.
$results_array = array();
// Roll through the values to check.
foreach ($values_to_check as $value) {
// Check if the array key exists in '$arrayMaster'.
if (array_key_exists($value, $arrayMaster)) {
// If it exists, add it to the '$results_array'.
$results_array[$value][] = $arrayMaster[$value];
// Roll through the values to check.
foreach ($arrayData as $arrayData_value) {
// Check if the array key exists in '$arrayData1'.
if (array_key_exists($value, $arrayData_value)) {
// If it exists, add it to the '$results_array'.
$results_array[$value][] = $arrayData_value[$value];
}
}
}
}
// Roll through the results array and use 'array_sum' to get a sum of values.
foreach ($results_array as $results_key => $results_value) {
echo $results_key . ' : ' . array_sum($results_value) . '<br />';
}

if value in end($array) contains something to to second last

I have a array with multiple elememts. I use end($array) to get the last element in the array. But if the last element contains a value it must take the second last element. But if the second last element also contains that value it must go to the next element. I already have written this code:
$g = end($array);
if($g != NULL && $g['MoreThanZero'] == true && $accountdata['bidding'] == 0) {
$v = end(array_pop($array));
} else {
$v = end($array);
}
In this code it will go till the second last element. How to make a "loop" which check last.. second last.... third last.... fourth last......
Use a little foreach, mixed with array_reverse() to get it works :
$accountdata['bidding'] = 0;
$array = array(
array('Value' => 10, 'MoreThanZero' => true),
array('Value' => -10, 'MoreThanZero' => false),
array('Value' => 20, 'MoreThanZero' => true),
array('Value' => -30, 'MoreThanZero' => false),
array('Value' => 30, 'MoreThanZero' => true),
array('Value' => 40, 'MoreThanZero' => true),
array('Value' => 50, 'MoreThanZero' => true)
);
$v = null;
foreach(array_reverse($array) as $g) {
if($g != NULL && $g['MoreThanZero'] == true && $accountdata['bidding'] == 0)
continue;
$v = $g;
break;
}
var_dump($v);
You can use array_reverse() function to change order of elements and then loop through array with foreach().
$test = array('one','two','three','three');
function getLastElement($array = array(),$exclude=null){
$list = array_reverse($array);
foreach($list as $item){
if($item!=$exclude) return $item;
}
return null;
}
var_dump(getLastElement($test,'three'));

Sum for values in my array

I have an array like below, and I want to do the total of values in a spefic manner where all values of val1_(.*) {regular expressions}, and similarly other values.
I have only specific vals like val1, val2, and val3.
My array is like:
$stats = Array
(
[ADDED_NEW_2012_06_12] => 16
[ADDED_OLD_2012_06_12] => 10
[ADD_LATER_2012_06_12] => 12
[ADDED_NEW_2012_06_11] => 16
[ADDED_OLD_2012_06_11] => 10
[ADD_LATER_2012_06_11] => 12
)
Can you please tell me how can i obtain my result. I don't know how to add such values using regex in php. Please help.
You don't necessarily need a regular expression if you can identify the values by the first part of the key.
Iterate over the array and create a new array with one element for each valX:
$totals = array();
// iterate over the array
foreach($array as $key => $value) {
$k = substr($key, 0, strpos($key, '_')); // get the first part (i.e. `valX`)
if(!isset($totals[$k])) { // if $totals['valX'] does not exist, initialize
$totals[$k] = 0;
}
$totals[$k] += $value; // sum
}
Reference: foreach, substr, strpos, isset
Do you mean this?
$array = array (
'val1_2012_06_12' => 16,
'val2_2012_06_12' => 10,
'val3_2012_06_12' => 12,
'val1_2012_06_11' => 16,
'val2_2012_06_11' => 10,
'val3_2012_06_11' => 12,
);
$sums = array();
foreach ($array as $key => $value) {
$regex = '~(?P<prefix>val\d+)_\d{4}_\d{2}_\d{2}~';
if (preg_match($regex, $key, $matches)) {
$sums[$matches['prefix']] += $value;
}
}
It will produce something like this, it will group sums by prefixes:
Array
(
[val1] => 32
[val2] => 20
[val3] => 24
)
Edit: updated to the refined question
You can match the key against a code, and create a sum from there like this with a simple foreach loop.
$array = array(
'ADDED_NEW_2012_06_12' => 16,
'ADDED_OLD_2012_06_12' => 10,
'ADD_LATER_2012_06_12' => 12,
'ADDED_NEW_2012_06_11' => 16,
'ADDED_OLD_2012_06_11' => 10,
'ADD_LATER_2012_06_11' => 12,
);
$sumarray = array();
foreach ($array as $key => $value)
{
$matches = array();
preg_match("/^(\w+?_\w+?)_/i", $key, $matches);
$key = $matches[1];
if (!isset($sumarray[$key]))
{
$sumarray[$key] = $value;
} else {
$sumarray[$key] = $sumarray[$key] + $value;
}
}
print_r($sumarray);
if you have just this tree type of value in array so you can use this:
$stats = Array(
'ADDED_NEW_2012_06_12' => 16,
'ADDED_OLD_2012_06_12' => 10,
'ADD_LATER_2012_06_12' => 12,
'ADDED_NEW_2012_06_11' => 16,
'ADDED_OLD_2012_06_11' => 10,
'ADD_LATER_2012_06_11' => 12
);
foreach($stats as $key => $value)
{
$substring=substr($key, 0 , 9);
if($substring=='ADDED_NEW')
#$ADDED_NEW += $value;
elseif($substring=='ADDED_OLD')
#$ADDED_OLD += $value;
else
#$ADD_LATER += $value;
}
echo 'ADDED_NEW : ' . $ADDED_NEW .'<br>ADDED_OLD : ' . $ADDED_OLD .'<br>ADD_LATER : ' . $ADD_LATER ;
Output :
ADDED_NEW : 32
ADDED_OLD : 20
ADD_LATER : 24
$sum = 0;
Foreach($object as $key=>$value){
$sum += $value;
}

Categories