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);
Related
I have following code that removes adjacent duplicates from the $myArray
<?php
$myArray = array(
0 => 0,
1 => 0,
2 => 1,
5 => 1,
6 => 2,
7 => 2,
8 => 2,
9 => 0,
10 => 0,
);
$previtem= NULL;
$newArray = array_filter(
$myArray,
function ($currentItem) use (&$previtem) {
$p = $previtem;
$previtem= $currentItem;
return $currentItem!== $p ;
}
);
echo "<pre>";
print_r($newArray);
?>
It works perfectly fine, but I have to change a condition bit for value 2. That means for other values we can pick first occurrence and ignore the others. But for 2, we need to pick last occurrence and ignore others.
So required output is
Array
(
[0] => 0 //first occurrence of 0 in $myArray
[2] => 1 //first occurrence of 1 in $myArray
[8] => 2 //last occurrence of 2 in the $myArray
[9] => 0 //first occurrence of 0 in $myArray
)
How to modify my code to achieve above result??
In reality I have multidimensional array, but for better explanation I have used single dimensional array here in the question.
UPDATE
My actual array is
$myArray = array(
0 => array("Value"=>0, "Tax" => "11.00"),
1 => array("Value"=>0, "Tax" => "12.00"),
2 => array("Value"=>1, "Tax" => "13.00"),
5 => array("Value"=>1, "Tax" => "14.00"),
6 => array("Value"=>2, "Tax" => "15.00"),
7 => array("Value"=>2, "Tax" => "16.00"),
8 => array("Value"=>2, "Tax" => "17.00"),
9 => array("Value"=>0, "Tax" => "18.00"),
10 => array("Value"=>0, "Tax" => "19.00"),
);
And my actual code
$previtem= NULL;
$newArray = array_filter(
$myArray,
function ($currentItem) use (&$previtem) {
$p["Value"] = $previtem["Value"];
$previtem["Value"] = $currentItem["Value"];
return $currentItem["Value"]!== $p["Value"] ;
}
);
Thanks
This should do what you are looking for.
function array_filter($a) {
$na = array();
$first = true;
$p = null;
$wantlast = false;
foreach ($a as $v) {
if ($wantlast) {
($v != $p) ? $na[] = $p: null;
}
$wantlast = ($v == 2) ? true : false;
if (!$wantlast) {
(($v != $p) || ($first))? $na[] = $v : null;
}
$p = $v;
$first = false;
}
return $na;
}
$myArray = array(
0 => 0,
1 => 0,
2 => 1,
5 => 1,
6 => 2,
7 => 2,
8 => 2,
9 => 0,
10 => 0,
);
$previtem= NULL;
$newArray = array_filter(
$myArray,
function ($currentItem, $key) use (&$previtem,$myArray) {
$p = $previtem;
if($currentItem != 2){
$previtem = $currentItem;
}else{
$lastkey = array_search(2,(array_reverse($myArray, true)));
if($key != $lastkey)
$currentItem = $previtem;
}
return $currentItem!== $p ;
}, ARRAY_FILTER_USE_BOTH
);
echo "<pre>";
print_r($newArray);
I have this array:
$actualPlan = 'medium';
$plans = array(
array(
'plans' => array(
'tiny' => 29,
'small' => 69,
'medium' => 179,
'big' => 359
)
)
);
During a foreach, I display the contents of plans of this array like this:
foreach($plans as $key => $data) {
foreach($data['plans'] as $plan => $rate) {
...
}
}
But how can I know the position of the $actualPlan ?
For example, for :
if $actualPlan == medium it should return me 3.
if $actualPlan == tiny it should return me 1.
Thanks.
inside the loop:
echo array_search($actualPlan, array_keys($rate)); // returns the index position as int
here will output 1,2,3,4 for the inputs 'tiny','small','medium','big'
Within the foreach($plans as $key => $data) {, you could make the conditional like this :
$current_plan = explode('___', $actualPlan);
$current_key = array_search($current_plan[0],array_keys($data['plans']));
foreach($data['plans'] as $plan => $rate) {
$current_iterated_key = array_search($plan,array_keys($data['plans']));
if ($current_iterated_key < $current_key) {
echo "$plan => Downgrade\r\n";
} elseif ($current_iterated_key > $current_key) {
echo "$plan => Upgrade\r\n";
} elseif($current_iterated_key == $current_key) {
echo "$plan => Current\r\n";
}
}
i have array like this
<?php
$array =
array
(
array (
0 => 1,
1 => 'php',
2 => 11,
3 => 11,
4 => 11,
5 => 11,
6 => 11,
),
array (
0 => 1,
1 => 'php',
2 => 11,
3 => 11,
4 => 11,
5 => 11,
6 => ,
),
);
and i want to search in this multi-array to find if the key [6] => is empty.if it was empty in any array return false so how to do this
foreach($array as $item)
{
foreach($item as $key=>$value)
{
print($key);
if($key=="6" && $value==NULL)
{
echo "found";
return false;
}else{
echo "not found";
return true;
}
}
}
$empty = false;
foreach($array as $item)
{
if(empty($item[6]))
{
$empty=true;
break;
}
}
return $empty;
First, it's recommended to use only one return in a function, so define a boolean value, and turn it to TRUE when the condition satisfies.
Second, use break to stop the cycle(s) running (saves runtime)
http://php.net/manual/en/control-structures.break.php
Third, check keys and values appropriately. Your keys are numeric and you are comparing to a string "6". Use empty() if you are interested in that the value is an empty-ish value. Be aware that a numeric zero is an empty value. If you are specifically interested in NULL value, use === operator
http://php.net/manual/en/function.empty.php
http://php.net/manual/en/language.operators.comparison.php
+1 See Yoda-style conditions
http://en.wikipedia.org/wiki/Yoda_conditions
++1 Use K&R style indent, or don't use it. But do not try! ;)
http://en.wikipedia.org/wiki/Indent_style#K.26R_style
$found = false;
foreach ($array as $item) {
foreach ($item as $key => $value) {
print($key);
if (6 == $key && NULL === $value) { // or use 'empty($value)'
echo "found";
$found = true;
break 2;
} else {
echo "not found";
}
}
}
return !$found;
Here's an alternate for PHP >= 5.5.0 that checks for '', 0, null and false:
return !array_diff($six = array_column($array, 6), array_filter($six));
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'));
I found this thread about picking the closest/nearest value from an array based upon a known value. What about if one wants to pick the two nearest values from an array looking at the same say?
$rebates = array(
1 => 0,
3 => 10,
5 => 25,
10 => 35)
$rebates = array(
1 => 0,
3 => 10,
5 => 25,
10 => 35);
function getArrayNeighborsByKey($array, $findKey) {
if ( ! array_key_exists($array, $findKey)) {
return FALSE;
}
$select = $prevous = $next = NULL;
foreach($array as $key => $value) {
$thisValue = array($key => $value);
if ($key === $findKey) {
$select = $thisValue;
continue;
}
if ($select !== NULL) {
$next = $thisValue;
break;
}
$previous = $thisValue;
}
return array(
'prev' => $previous,
'current' => $select,
'next' => $next
);
}
See it!
By "two nearest" you mean the two smaller than or equal to the value of $items?
Anyway, starting from the answer to that other thread, which is
$percent = $rebates[max(array_intersect(array_keys($rebates),range(0,$items)))];
You can go to
$two_nearest = array_slice(array_intersect(array_keys($rebates),range(0,$items)), -2);
$most_near = $rebates[$two_nearest[1]];
$less_near = $rebates[$two_nearest[0]];
This can probably be reduced to an one-liner using array_map, but I think it's overdone already.
$rebates = array(
1 => 0,
3 => 10,
5 => 25,
10 => 35)
$distances = array();
foreach($rebates as $key=>$item) {
if ($key == 5) continue;
$distances = abs($rebates[5] - $item);
}
sort($distances, SORT_NUMERIC)
Now you have an array with all the items in the array with their distance to $rebates[5] sorted. So you can get the two closest ones.
Or three closest ones. Whatever.
Just keep in mind that 2 items can have the same distance.