How to delete object from array inside foreach loop? - php

I iterate through an array of objects and want to delete one of the objects based on it's 'id' property, but my code doesn't work.
foreach($array as $element) {
foreach($element as $key => $value) {
if($key == 'id' && $value == 'searched_value'){
//delete this particular object from the $array
unset($element);//this doesn't work
unset($array,$element);//neither does this
}
}
}
Any suggestions. Thanks.

foreach($array as $elementKey => $element) {
foreach($element as $valueKey => $value) {
if($valueKey == 'id' && $value == 'searched_value'){
//delete this particular object from the $array
unset($array[$elementKey]);
}
}
}

Be careful with the main answer.
with
[['id'=>1,'cat'=>'vip']
,['id'=>2,'cat'=>'vip']
,['id'=>3,'cat'=>'normal']
and calling the function
foreach($array as $elementKey => $element) {
foreach($element as $valueKey => $value) {
if($valueKey == 'cat' && $value == 'vip'){
//delete this particular object from the $array
unset($array[$elementKey]);
}
}
}
it returns
[2=>['id'=>3,'cat'=>'normal']
instead of
[0=>['id'=>3,'cat'=>'normal']
It is because unset does not re-index the array.
It reindexes. (if we need it)
$result=[];
foreach($array as $elementKey => $element) {
foreach($element as $valueKey => $value) {
$found=false;
if($valueKey === 'cat' && $value === 'vip'){
$found=true;
$break;
}
if(!$found) {
$result[]=$element;
}
}
}

It looks like your syntax for unset is invalid, and the lack of reindexing might cause trouble in the future. See: the section on PHP arrays.
The correct syntax is shown above. Also keep in mind array-values for reindexing, so you don't ever index something you previously deleted.

This should do the trick.....
reset($array);
while (list($elementKey, $element) = each($array)) {
while (list($key, $value2) = each($element)) {
if($key == 'id' && $value == 'searched_value') {
unset($array[$elementKey]);
}
}
}

You can also use references on foreach values:
foreach($array as $elementKey => &$element) {
// $element is the same than &$array[$elementKey]
if (isset($element['id']) and $element['id'] == 'searched_value') {
unset($element);
}
}

I'm not much of a php programmer, but I can say that in C# you cannot modify an array while iterating through it. You may want to try using your foreach loop to identify the index of the element, or elements to remove, then delete the elements after the loop.

Related

Modify array during multiple foreach loop iterations

I've to update data for array which has 4 foreach loops,
foreach ($dta['hotels']['hotels'] as $key => &$value) {
foreach ($value['rooms'] as $key1 => $value1) {
foreach ($value1['rates'] as $key2 => $value2) {
foreach ($value2['shiftRates'] as $key3 => &$value3) {
$value3['net'] = 0.000072*$value3['net'];
$value3['sellingRate'] = 0.000072*$value3['sellingRate'];
var_dump($value3['sellingRate']);
}
}
}
$value['currency'] = 'USD';
}
I want to update data of very deep 4th foreach loop, which isn't updating data, where as first loop data update was possible.
i've tried to put "&" but in first loop it worked and in 4th loop it's not working.
Any possible solutions ?
You have all keys, you can use these to modify your values :
$dta['hotels']['hotels'][$key]['rooms'][$key1]['rates'][$key2]['shiftRates'][$key3]['sellingRate'] = 0.000072 * $value3['sellingRate'];
As long as there are no other net or sellingRate keys somewhere else in the array that you don't want to modify, you can do this more simply with array_walk_recursive.
array_walk_recursive($dta, function(&$value, $key) {
if ($key === 'net' || $key === 'sellingRate') {
$value *= 0.000072;
}
});

Two arrays: if a key in the first array is empty, set the same key in the second array to be empty?

I have this array that has two $rows:
I'd like the second array's display to be based on the first array but I don't think I have it set up properly:
$rows = &$vars['rows'];
foreach ($rows[0] as $key => $value) {
if (strpos($key, 'views') === 0 && empty($value)) {
$rows[1][$key] = '';
unset($vars['header'][$key]);
}
}
This is the output from the code, you can see the table doesn't seem aligned properly:
You need to loop over the whole array and then loop over the inner data as well. Simply you need two foreach loops.
$rows = $vars;
foreach ($rows as $occ => $outer ) {
foreach ($outer as $key => $value) {
if (strpos($key, 'views') === 0 && $value =='') {
unset($vars[$occ][$key]);
}
}
}

traversing an array in php [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Loop an array of array
So I know how to traverse an array of even key => value (associative), but I have a weird array where I need to walk through it and print out values:
$object_array = array(
'type' => 'I am type',
array(
'property' => 'value',
'property_2' => 'value_2'
)
);
What I thought I could do is:
foreach($object as $key=>$vlaue){
//what now?
}
So as you can see I am lost, how do I walk through the next array?
You can try:
function traverse($array) {
foreach ($array as $key => $value) {
if (is_array($value)) {
traverse($array);
continue;
}
echo $value;
}
}
foreach($object as $key=>$value){
if( is_array($value) ) {
foreach($value as $key2=>$value2) {
//stuff happens
}
} else {
//other stuff
]
}
Try:
foreach($object_array as $value) {
if(!is_array($value))
echo $value;
else {
foreach($value as $m)
echo $m;
}
}
Manual for foreach
In your for loop you could do:
if(is_array($object[$key]))
//process inner array here
It depends on how deep your arrays go, if you have arrays of arrays of arrays...and so on, a different method would be better, but if you just have one level this is a pretty simple way of doing it.
Well, you could do something like this:
foreach($object_array as $key=>$value)
{
if(is_array($value) {
foreach($value as $k=>$v) {
echo $k." - ".$v;
}
} else {
echo $key." - ".$value;
}
}
An alternative with array_walk_recursive():
function mydebug($value, $key) {
echo $key . ' => ' . $value . PHP_EOL;
}
array_walk_recursive($object_array, 'mydebug');
Handy if you doing something simple with the values (e.g. just echo ing).

How to get index's value from $_POST using foreach

I want to know the correct code to detect only numerical $_POST fields coming from the form.
Please correct my code.
foreach ($_POST as $vals) {
if (is_numeric($vals)) {
if (is_numeric($vals[$i]) && ($vals[$i]!="0")) {
//do something
}
}
$_POST = array_filter($_POST, "is_numeric");
The above will remove all non-numeric array items.
foreach (array_filter($_POST, "is_numeric") as $key => $val)
{
// do something
echo "$key is equal to $val which is numeric.";
}
Update:
If you only want those like $_POST[1], $_POST[2], etc..
foreach ($_POST as $key => $vals){
if (is_numeric($key)){
//do something
}
}
try:
foreach ($_POST as $key => $vals){
//this is read: $_POST[$key]=$value
if (is_numeric($vals) && ($vals!="0")){
//do something
}
}
if(isset($_POST)){
foreach($_POST as $key => $value){
if(is_numeric($key)){
echo $value;
}
}
}
Compare the keys
Try this:
foreach ($_POST as $key => $val)
{
if (is_numeric($key))
{
// do something
}
}
The following code with isset() trying to work on an array is invalid.
if(isset($_POST)){ //isset() only works on variables and array elements.
foreach($_POST as $key => $value){
if(is_numeric($key)){
echo $value;
}
}
foreach ($_POST as $key => $val)
{
if (is_numeric($key))
{
// do something
}
}
Better, but now foreach will make a copy of $_POST and put in in memory for the duration of the loop (Programming PHP: Ch. 6, p. 128-129). I hope buffer overflows or out of memory errors don't jump up and bite you. :-)
Perhaps it would be wiser to determine some facts about $_POST with is_array(), empty(), count() and others before getting started, such as ...
if(is_array($_POST) && !empty($_POST))
{
if(count($_POST) === count($arrayOfExpectedControlNames))
{
//Where the the values for the $postKeys have already been validated some...
if(in_array($arrayOfExpectedControlNames, $postKeys))
{
foreach ($_POST as $key => $val) //If you insist on using foreach.
{
if (is_numeric($key))
{
// do something
}
else
{
//Alright, already. Enough!
}
}
}
else
{
//Someone is pulling your leg!
}
}
else
{
//Definitely a sham!
}
}
else
{
//It's a sham!
}
Still, the $val values need some validation, but I'm sure you are up on that.

Search multidimensional arrays for specific keys and output their data

I have following array construction: $array[$certain_key][some_text_value]
And in a while loop, I want to print the data from the array, where $certain_key is a specific value.
I know how to loop through multidimensional arrays, which is not the complete solution to this problem:
foreach ($a as $v1) {
foreach ($v1 as $v2) {
echo "$v2\n";
}
}
I do not want to loop the whole array each time, but only when $certain_key is matched.
EDIT: to be more exact, this is what I'm trying to do:
$array[$array_key][some_text];
while reading from db {
//print array where a value returned from the db = $array_key
}
while ($row = fetch()) {
if (isset($array[$row['db_id']])) {
foreach ($array[$row['db_id']] as $some_text_value => $some_text_values_value) {
echo ...
}
}
}
foreach ($array as $certain_key => $value) {
if($certain_key == $row['db_id']) {
foreach ($value as $some_text_value) {
echo "$v2\n";
}
}
}
You mean like
foreach($array[$certain_key] as $k => $v)
{
do_stuff();
}
?
Maybe you're looking for array_key_exists? It works like this:
if(array_key_exists($certain_key, $array)) {
// do something
}
<?php
foreach ($a as $idx => $value) {
// replace [search_value] with whatever key you are looking for
if ('[search_value]' == $idx) {
// the key you are looking for is stored as $idx
// the row you are looking for is stored as $value
}
}

Categories