Which is a more efficient way of comparing an array's keys with a template and filtering out empty values? Then operating on the remaining parts of the array?
$arr = array_intersect_key(array_filter($arr), $this->arrTemplate);
foreach ($arr as $_k => $_v) {
//Do something
Or this:
foreach ($arr as $_k => $_v) {
if (array_key_exists($_k, $this->arrTemplate)) {
if (empty($_v)) {
continue;
}
//Do something
}
}
Also as a side question, how can I measure efficiency for myself?
Related
Currently, I am looping through 4 foreach loops:
foreach ($level0_array as $level0_key => $level1_array) {
//do something
foreach ($level1_array as $level1_key => $level2_array) {
//do something
foreach ($level2_array as $level2_key => $level3_array) {
//do something
foreach ($level3_array as $level3_key => $level4_value) {
//do something
}
}
}
}
Is it possible to do it if this loop is inside a function and it is supposed to get the number of levels to loop through dynamically? (Assuming in this case that $level0_array have enough levels in it)
i.e.
function ($level0_array, $number_of_levels) {
// loop. . .
}
Yes, there is, and it is called recursion:
function loopThroughLevels($level_array, $number_of_levels_left) {
foreach ($level_array as $level_key => $level_value) {
// do something
if (is_array($level_value) &&
($number_of_levels_left > 0)) {
loopThroughLevels($level_value, $number_of_levels_left - 1);
}
}
}
Here the function calls itself again, looping through a sub-level of the array as long as there is an array to loop through and there are levels left you want to loop through.
I'm trying to remove duplicated entries where value and type are both equal on a multidimensional associative array, but only using recursion and without array_unique. All keys are associative.
I tried this, and I'm getting the same result as the main array. My logic seems to fail me at this late hour.
function rmDuplicates(&$array) {
$uniqueArray = array();
foreach($array as $k=>$v) {
if (is_array($v)) {
$uniqueArray[$k] = rmDuplicates($v);
} else {
if (!in_array($v, $uniqueArray)) {
$uniqueArray[] = $v;
}
}
}
return $uniqueArray;
}
I am writing a shopping cart session handler class and I find myself repeating this certain chunk of code which searches a multidimensional associative array for a value match.
foreach($_SESSION['cart'] as $k => $v){
if($v['productID'] == $productID){
$key = $k;
$this->found = true;
}
}
I am repeating this when trying to match different values in the array.
Would there be an easy to to create a method whereby I pass the key to search and the value. (Sounds simple now I read that back but for some reason have had no luck)
Sounds like you want something like this:
function findKey(array $array, $wantedKey, $match) {
foreach ($array as $key => $value){
if ($value[$wantedKey] == $match) {
return $key;
}
}
}
Now you can do:
$key = findKey($_SESSION['cart'], 'productID', $productID);
if ($key === null) {
// no match in the cart
} else {
// there was a match
}
Hi I have a PHP array with a variable number of keys (keys are 0,1,2,3,4.. etc)
I want to process the first value differently, and then the rest of the values the same.
What's the best way to do this?
$first = array_shift($array);
// do something with $first
foreach ($array as $key => $value) {
// do something with $key and $value
}
I would do this:
$firstDone = FALSE;
foreach ($array as $value) {
if (!$firstDone) {
// Process first value here
$firstDone = TRUE;
} else {
// Process other values here
}
}
...but whether that is the best way is debatable. I would use foreach over any other method, because then it does not matter what the keys are.
Here is one way:
$first = true;
foreach($array as $key => $value) {
if ($first) {
// something different
$first = false;
}
else {
// regular logic
}
}
$i = 0;
foreach($ur_array as $key => $val) {
if($i == 0) {
//first index
}
else {
//do something else
}
$i++;
}
I would do it like this if you're sure the array contains at least one entry:
processFirst($myArray[0]);
for ($i=1; $i<count($myArray); $1++)
{
processRest($myArray[$i]);
}
Otherwise you'll need to test this before processing the first element
I've made you a function!
function arrayCallback(&$array) {
$callbacks = func_get_args(); // get all arguments
array_shift($callbacks); // remove first element, we only want the callbacks
$callbackindex = 0;
foreach($array as $value) {
// call callback
$callbacks[$callbackindex]($value);
// make sure it keeps using last callback in case the array is bigger than the amount of callbacks
if(count($callbacks) > $callbackindex + 1) {
$callbackindex++;
}
}
}
If you call this function, it accepts an array and infinite callback arguments. When the array is bigger than the amount of supplied functions, it stays at the last function.
You can simply call it like this:
arrayCallback($array, function($value) {
print 'callback one: ' . $value;
}, function($value) {
print 'callback two: ' . $value;
});
EDIT
If you wish to avoid using a function like this, feel free to pick any of the other correct answers. It's just what you prefer really. If you're repeatedly are planning to loop through one or multiple arrays with different callbacks I suggest to use a function to re-use code. (I'm an optimisation freak)
Is there a built in php function that allows me to set a value of an array based on a matching key? Maybe i've been writing too much SQL lately, but i wish I could perform the following logic without writing out nested foreach array like the following:
foreach($array1 AS $k1 => $a1) {
foreach($array2 AS $a2) {
if($a1['id'] == $a2['id']) {
$array[$k1]['new_key'] = $a2['value'];
}
}
}
Is there a better way to do this? In SQL logic, it would be "SET array1.new_key = x WHERE array1.id = array2.id". Again, i've been writing too much SQL lately :S
When I need to do this, I use a function to first map the values of one array by id:
function convertArrayToMap(&$list, $attribute='id') {
$result = array();
foreach ($list as &$item) {
if (is_array($item) && array_key_exists($attribute, $item)) {
$result[$item[$attribute]] = &$item;
}
}
return $result;
}
$map = convertArrayToMap($array1);
Then iterate through the other array and assign the values:
foreach ($array2 AS $a2) {
$id = $a2['id'];
$map[$id]['new_key'] = $a2['value'];
}
This are less loops overall even for one pass, and it's convenient for further operations in the future.
This one is fine and correct
foreach(&$array1 AS &$a1) {
foreach($array2 AS $a2) {
if($a1['id'] == $a2['id']) {
$a1['new_key'] = $a2['value'];
}
}
}