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'));
Related
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);
I need elements of array 1 that are not present in array 2 based on the 'value' key only.
Array1
$array1 = array(
array('value' => 113214, 'revision_id' => 2047152),
array('value' => 236462, 'revision_id' => 2045678),
array('value' => 236541, 'revision_id' => 2047155)
);
Array2
$array2 = array(
array('value' => 113214, 'revision_id' => 2047152),
array('value' => 236461, 'revision_id' => 2047153),
array('value' => 236541, 'revision_id' => 2047155)
);
I need the output as below, the difference of arrays should be based on Value
$output = array(
array('value' => 236462, 'revision_id' => 2045678)
);
Just do a nested foreach loop and check the condition hope its helps you :
$arraycheck= array();
foreach($newData as $data1) {
$duplicatecheck = false;
foreach($oldData as $data2) {
if($data1['value'] === $data2['value'] && $data1['revision_id'] === $data2['revision_id']) $duplicatecheck = true;
}
if($duplicatecheck === false) $arraycheck[] = $data1;
}
First, use array_column to get the values of 'value' from array2 into a one-dimensional array:
$a2values = array_column($array2, 'value');
Then use those values to array_filter array1.
$result = array_filter($array1, function($item) use ($a2values) {
// only keep items with values not in array2
return !in_array($item['value'], $a2values);
});
You can use array_udiff which accepts last parameter as callback, and you can define your comparison there easily.
$array1 = [
['value' => '113214', 'revision_id' => '2047152'],
['value' => '236462', 'revision_id' => '2045678'],
['value' => '236541', 'revision_id' => '2047155'],
];
$array2 = [
['value' => '113214', 'revision_id' => '2047152'],
['value' => '236461', 'revision_id' => '2047153'],
['value' => '236541', 'revision_id' => '2047155'],
];
$result = array_udiff ($array1, $array2, function($x, $y) {
return $x['value'] - $y['value'];
});
print_r($result);
taken from: https://gist.github.com/wrey75/c631f6fe9c975354aec7
function my_array_diff($arr1, $arr2) {
$diff = array();
// Check the similarities
foreach( $arr1 as $k1=>$v1 ){
if( isset( $arr2[$k1]) ){
$v2 = $arr2[$k1];
if( is_array($v1) && is_array($v2) ){
// 2 arrays: just go further...
// .. and explain it's an update!
$changes = self::diff($v1, $v2);
if( count($changes) > 0 ){
// If we have no change, simply ignore
$diff[$k1] = array('upd' => $changes);
}
unset($arr2[$k1]); // don't forget
}
else if( $v2 === $v1 ){
// unset the value on the second array
// for the "surplus"
unset( $arr2[$k1] );
}
else {
// Don't mind if arrays or not.
$diff[$k1] = array( 'old' => $v1, 'new'=>$v2 );
unset( $arr2[$k1] );
}
}
else {
// remove information
$diff[$k1] = array( 'old' => $v1 );
}
}
// Now, check for new stuff in $arr2
foreach( $arr2 as $k=>$v ){
// OK, it is quite stupid my friend
$diff[$k] = array( 'new' => $v );
}
return $diff;
}
usage:
$diff = my_array_diff($arr1, $arr2);
var_dump($diff);
I'm trying to remove an object from an array of objects by its' index. Here's what I've got so far, but i'm stumped.
$index = 2;
$objectarray = array(
0=>array('label'=>'foo', 'value'=>'n23'),
1=>array('label'=>'bar', 'value'=>'2n13'),
2=>array('label'=>'foobar', 'value'=>'n2314'),
3=>array('label'=>'barfoo', 'value'=>'03n23')
);
//I've tried the following but it removes the entire array.
foreach ($objectarray as $key => $object) {
if ($key == $index) {
array_splice($object, $key, 1);
//unset($object[$key]); also removes entire array.
}
}
Any help would be appreciated.
Updated Solution
array_splice($objectarray, $index, 1); //array_splice accepts 3 parameters
//(array, start, length) removes the given array and then normalizes the index
//OR
unset($objectarray[$index]); //removes the array at given index
$reindex = array_values($objectarray); //normalize index
$objectarray = $reindex; //update variable
array_splice($objectarray, $index, 1);
//array_splice accepts 3 parameters (array, start, length) and removes the given
//array and then normalizes the index
//OR
unset($objectarray[$index]); //removes the array at given index
$reindex = array_values($objectarray); //normalize index
$objectarray = $reindex; //update variable
You have to use the function unset on your array.
So its like that:
<?php
$index = 2;
$objectarray = array(
0 => array('label' => 'foo', 'value' => 'n23'),
1 => array('label' => 'bar', 'value' => '2n13'),
2 => array('label' => 'foobar', 'value' => 'n2314'),
3 => array('label' => 'barfoo', 'value' => '03n23')
);
var_dump($objectarray);
foreach ($objectarray as $key => $object) {
if ($key == $index) {
unset($objectarray[$index]);
}
}
var_dump($objectarray);
?>
Remember, your array will have odd indexes after that and you must (if you want) reindex it.
$foo2 = array_values($objectarray);
in that case you won't need that foreach just unset directly
unset($objectarray[$index]);
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.
I have a deep and long array (matrix). I only know the product ID.
How found way to product?
Sample an array of (but as I said, it can be very long and deep):
Array(
[apple] => Array(
[new] => Array(
[0] => Array([id] => 1)
[1] => Array([id] => 2))
[old] => Array(
[0] => Array([id] => 3)
[1] => Array([id] => 4))
)
)
I have id: 3, and i wish get this:
apple, old, 0
Thanks
You can use this baby:
function getById($id,$array,&$keys){
foreach($array as $key => $value){
if(is_array( $value )){
$result = getById($id,$value,$keys);
if($result == true){
$keys[] = $key;
return true;
}
}
else if($key == 'id' && $value == $id){
$keys[] = $key; // Optional, adds id to the result array
return true;
}
}
return false;
}
// USAGE:
$result_array = array();
getById( 3, $products, $result_array);
// RESULT (= $result_array)
Array
(
[0] => id
[1] => 0
[2] => old
[3] => apple
)
The function itself will return true on success and false on error, the data you want to have will be stored in the 3rd parameter.
You can use array_reverse(), link, to reverse the order and array_pop(), link, to remove the last item ('id')
Recursion is the answer for this type of problem. Though, if we can make certain assumptions about the structure of the array (i.e., 'id' always be a leaf node with no children) there's further optimizations possible:
<?php
$a = array(
'apple'=> array(
'new'=> array(array('id' => 1), array('id' => 2), array('id' => 5)),
'old'=> array(array('id' => 3), array('id' => 4, 'keyname' => 'keyvalue'))
),
);
// When true the complete path has been found.
$complete = false;
function get_path($a, $key, $value, &$path = null) {
global $complete;
// Initialize path array for first call
if (is_null($path)) $path = array();
foreach ($a as $k => $v) {
// Build current path being tested
array_push($path, $k);
// Check for key / value match
if ($k == $key && $v == $value) {
// Complete path found!
$complete= true;
// Remove last path
array_pop($path);
break;
} else if (is_array($v)) {
// **RECURSION** Step down into the next array
get_path($v, $key, $value, $path);
}
// When the complete path is found no need to continue loop iteration
if ($complete) break;
// Teardown current test path
array_pop($path);
}
return $path;
}
var_dump( get_path($a, 'id', 3) );
$complete = false;
var_dump( get_path($a, 'id', 2) );
$complete = false;
var_dump( get_path($a, 'id', 5) );
$complete = false;
var_dump( get_path($a, 'keyname', 'keyvalue') );
I tried this for my programming exercise.
<?php
$data = array(
'apple'=> array(
'new'=> array(array('id' => 1), array('id' => 2), array('id' => 5)),
'old'=> array(array('id' => 3), array('id' => 4))
),
);
####print_r($data);
function deepfind($data,$findfor,$depth = array() ){
foreach( $data as $key => $moredata ){
if( is_scalar($moredata) && $moredata == $findfor ){
return $depth;
} elseif( is_array($moredata) ){
$moredepth = $depth;
$moredepth[] = $key;
$isok = deepfind( $moredata, $findfor, $moredepth );
if( $isok !== false ){
return $isok;
}
}
}
return false;
}
$aaa = deepfind($data,3);
print_r($aaa);
If you create the array once and use it multiple times i would do it another way...
When building the initial array create another one
$id_to_info=array();
$id_to_info[1]=&array['apple']['new'][0];
$id_to_info[2]=&array['apple']['new'][2];