Unsetting array values in a foreach loop [duplicate] - php

This question already has answers here:
How do you remove an array element in a foreach loop?
(6 answers)
Closed 6 years ago.
I have a foreach loop set up to go through my array, check for a certain link, and if it finds it removes that link from the array.
My code:
foreach($images as $image)
{
if($image == 'http://i27.tinypic.com/29yk345.gif' ||
$image == 'http://img3.abload.de/img/10nx2340fhco.gif' ||
$image == 'http://i42.tinypic.com/9pp2456x.gif')
{
unset($images[$image]);
}
}
But it doesn't remove the array entires. It's probably something to do with $images[$image], as that's not the key of the array entry, only the content? Is there a way to do this without incorporating a counter?
Thanks.
EDIT: Thanks guys, but now I have another problem where the array entries don't actually get deleted.
My new code:
foreach($images[1] as $key => $image)
{
if($image == 'http://i27.tinypic.com/29yk345.gif')
$image == 'http://img3.abload.de/img/10nx2340fhco.gif' ||
$image == 'http://i42.tinypic.com/9pp2456x.gif')
{
unset($images[$key]);
}
}
$images is actuallty a two-dimensional array now hence why I need $images[1]. I have checked and it successfully goes around the array elements, and some elements do actually have some of those URLs in that I wish to delete, but they're not getting deleted. This is my $images array:
Array
(
[0] => Array
(
[0] => useless
[1] => useless
[2] => useless
[3] => useless
[4] => useless
)
[1] => Array
(
[0] => http://i27.tinypic.com/29yk345.gif
[1] => http://img3.abload.de/img/10nx2340fhco.gif
[2] => http://img3.abload.de/img/10nx2340fhco.gif
[3] => http://i42.tinypic.com/9pp2456x.gif
)
)
Thanks!

foreach($images as $key => $image)
{
if(in_array($image, array(
'http://i27.tinypic.com/29ykt1f.gif',
'http://img3.abload.de/img/10nxjl0fhco.gif',
'http://i42.tinypic.com/9pp2tx.gif',
))
{
unset($images[$key]);
}
}

Try that:
foreach ($images[1] as $key => &$image) {
if (yourConditionGoesHere) {
unset($images[1][$key])
}
}
unset($image); // detach reference after loop
Normally, foreach operates on a copy of your array so any changes you make, are made to that copy and don't affect the actual array.
So you need to unset the values via $images[$key];
The reference on &$image prevents the loop from creating a copy of the array which would waste memory.

To answer the initial question (after your edit), you need to unset($images[1][$key]);
Now some more infos how PHP works:
You can safely unset elements of the array in foreach loop, and it doesn't matter if you have & or not for the array item. See this code:
$a=[1,2,3,4,5];
foreach($a as $key=>$val)
{
if ($key==3) unset($a[$key]);
}
print_r($a);
This prints:
Array
(
[0] => 1
[1] => 2
[2] => 3
[4] => 5
)
So as you can see, if you unset correct thing within the foreach loop, everything works fine.

You can use the index of the array element to remove it from the array, the next time you use the $list variable, you will see that the array is changed.
Try something like this
foreach($list as $itemIndex => &$item) {
if($item['status'] === false) {
unset($list[$itemIndex]);
}
}

$image is in your case the value of the item and not the key. Use the following syntax to get the key too:
foreach ($images as $key => $value) {
/* … */
}
Now you can delete the item with unset($images[$key]).

One solution would be to use the key of your items to remove them -- you can both the keys and the values, when looping using foreach.
For instance :
$arr = array(
'a' => 123,
'b' => 456,
'c' => 789,
);
foreach ($arr as $key => $item) {
if ($item == 456) {
unset($arr[$key]);
}
}
var_dump($arr);
Will give you this array, in the end :
array
'a' => int 123
'c' => int 789
Which means that, in your case, something like this should do the trick :
foreach($images as $key => $image)
{
if($image == 'http://i27.tinypic.com/29yk345.gif' ||
$image == 'http://img3.abload.de/img/10nx2340fhco.gif' ||
$image == 'http://i42.tinypic.com/9pp2456x.gif')
{
unset($images[$key]);
}
}

foreach($images as $key=>$image)
{
if($image == 'http://i27.tinypic.com/29ykt1f.gif' ||
$image == 'http://img3.abload.de/img/10nxjl0fhco.gif' ||
$image == 'http://i42.tinypic.com/9pp2tx.gif')
{ unset($images[$key]); }
}
!!foreach($images as $key=>$image
cause $image is the value, so $images[$image] make no sense.

You would also need a
$i--;
after each unset to not skip an element/
Because when you unset $item[45], the next element in the for-loop should be $item[45] - which was [46] before unsetting. If you would not do this, you'd always skip an element after unsetting.

Sorry for the late response, I recently had the same problem with PHP and found out that when working with arrays that do not use $key => $value structure, when using the foreach loop you actual copy the value of the position on the loop variable, in this case $image. Try using this code and it will fix your problem.
for ($i=0; $i < count($images[1]); $i++)
{
if($images[1][$i] == 'http://i27.tinypic.com/29yk345.gif' ||
$images[1][$i] == 'http://img3.abload.de/img/10nx2340fhco.gif' ||
$images[1][$i] == 'http://i42.tinypic.com/9pp2456x.gif')
{
unset($images[1][$i]);
}
}
var_dump($images);die();

Related

remove array from multidimensional array with unset

Is it possible to remove an array from an array? This is how the array looks...
[1042] => Array
(
[contact_name] => XXX
[email] =>
[id] => XXX
)
[1043] => Array
(
[contact_name] => XXX
[email] => XXX
[id] => XXX
)
code...
foreach($contacts as &$contact){
if(empty($contact['email']) || $contact['email'] == '')
unset($contact);
}
It's possible if you use the arrays keys instead of references.
foreach($contacts as $key => $contact){
if(empty($contact['email']))
unset($contacts[$key]);
}
I also removed the $contact['email] == '' since the empty()-check covers empty (!) strings as well.
Note: In general, avoid using references together with foreach if you can. Using them can easily lead to unwanted side effects.
Make use of the key and value pair when defining the foreach loop.
Knowing the key of the value (in this case a subarray) you want to unset, you can do it like below:
foreach($contacts as $key => $contact {
if(empty($contact['email']) || $contact['email'] == '') {
unset($contacts[$key]);
}
}
It looks like you want to filter out items that do not have a value in the email field, if that is the case then use PHP's array_filter method:
$filtered = array_filter($array, function($contact) {
if(!empty($contact['email']) && $contact['email'] != '') {
return $contact;
}
});
Fiddle: Live Demo
had to do traditional for loop and use index to remove. Could not be done with foreach loop.
Edit
// this is the code that worded
for($i = 0; $i <= count($other_array); $i++){
if( !array_key_exists( "testing", $other_array[$i] ) )
unset($other_array[$i]);
}

PHP multidimensional array not giving output

I've tried to display this information tons of times, i've looked all over stackoverflow and just can't find an answer, this isn't a duplicate question, none of the solutions on here work. I've a json array which is stored as a string in a database, when it's taken from the database it's put into an array using json_decode and looks like this
Array
(
[0] => Array
(
[0] => Array
(
)
[1] => Array
(
[CanViewAdminCP] => Array
(
[Type] => System
[Description] => Grants user access to view specific page
[Colour] => blue
)
)
)
)
However, when i try to loop through this, it just returns nothing, I've tried looping using keys, i've tried foreach loops, nothing is returning the values, I'm looking to get the Array key so "CanViewAdminCP" and then the values inside that key such as "Type" and "Description".
Please can anybody help? thankyou.
Use a recursive function to search for the target key CanViewAdminCP recursively, as follows:
function find_value_by_key($haystack, $target_key)
{
$return = false;
foreach ($haystack as $key => $value)
{
if ($key === $target_key) {
return $value;
}
if (is_array($value)) {
$return = find_value_by_key($value, $target_key);
}
}
return $return;
}
Example:
print_r(find_value_by_key($data, 'CanViewAdminCP'));
Array
(
[Type] => System
[Description] => Grants user access to view specific page
[Colour] => blue
)
Visit this link to test it.
You have a 4 level multidimensional array (an array containing an array containing an array containing an array), so you will need four nested loops if you want to iterate over all keys/values.
This will output "System" directly:
<?php echo $myArray[0][1]['CanViewAdminCP']['Type']; ?>
[0] fetches the first entry of the top level array
[1] fetches the second entry of that array
['CanViewAdminCP'] fetches that keyed value of the third level array
['Type'] then fetches that keyed value of the fourth level array
Try this nested loop to understand how nested arrays work:
foreach($myArray as $k1=>$v1){
echo "Key level 1: ".$k1."\n";
foreach($v1 as $k2=>$v2){
echo "Key level 2: ".$k2."\n";
foreach($v2 as $k3=>$v3){
echo "Key level 3: ".$k3."\n";
}
}
}
Please consider following code which will not continue after finding the first occurrence of the key, unlike in Tommassos answer.
<?php
$yourArray =
array(
array(
array(),
array(
'CanViewAdminCP' => array(
'Type' => 'System',
'Description' => 'Grants user access to view specific page',
'Colour' => 'blue'
)
),
array(),
array(),
array()
)
);
$total_cycles = 0;
$count = 0;
$found = 0;
function searchKeyInMultiArray($array, $key) {
global $count, $found, $total_cycles;
$total_cycles++;
$count++;
if( isset($array[$key]) ) {
$found = $count;
return $array[$key];
} else {
foreach($array as $elem) {
if(is_array($elem))
$return = searchKeyInMultiArray($elem, $key);
if(!is_null($return)) break;
}
}
$count--;
return $return;
}
$myDesiredArray = searchKeyInMultiArray($yourArray, 'CanViewAdminCP');
print_r($myDesiredArray);
echo "<br>found in depth ".$found." and traversed ".$total_cycles." arrays";
?>

How can i add element to my array under a specific key?

How can i add element to my array under a specific key?
This is my array output before i use foreach. As you can see, the error field is empty. I want to fill it out.
Array (
[0] => Array (
[transactionid] => 2223
[created] => 26-02-13 14:07:00
[cardid] => 10102609
[pricebefordiscount] => 68900
[error] =>
)
This is my foreach. As you can see i already tried to make this work by implementing $arrayname['index'] = $value;. But this does not work, nothing comes out when i spit out in a print_r. Why is this happening?
foreach ($samlet as $key)
{
if ($key['pricebefordiscount'] > '200000')
{
$samlet['error'] = "O/2000";
}
if ($key['cardid'] === '88888888')
{
$samlet['error'] = "Testscan";
}
}
This is the desired output:
Array (
[0] => Array (
[transactionid] => 2223
[created] => 26-02-13 14:07:00
[cardid] => 10102609
[pricebefordiscount] => 68900
[error] => "Testscan"
)
Change your foreach, so you have the indexes used in the "main" $samlet array:
foreach($samlet as $key => $array)
{
if ($array['cardid'] === '88888888')
{
$samlet[$key]['error'] = '0/2000';
}
}
And so on...
Try this :
foreach ($samlet as &$key){
if ($key['pricebefordiscount'] > '200000'){
$key['error'] = "O/2000";
}
if ($key['cardid'] === '88888888'){
$key['error'] = "Testscan";
}
}
According to PHP manual:
In order to be able to directly modify array elements within the loop precede $value with &. In that case the value will be assigned by reference.
So your code should looke like this:
<?php
foreach ($samlet as &$key)
{
if ($key['pricebefordiscount'] > '200000')
{
$key['error'] = "O/2000";
}
if ($key['cardid'] === '88888888')
{
$key['error'] = "Testscan";
}
}
TRY THIS
foreach ($samlet as $key=>$value)
{
if ($value['pricebefordiscount'] > '200000')
{
$samlet[$key]['error'] = "O/2000";
}
if ($value['cardid'] === '88888888')
{
$samlet[$key]['error'] = "Testscan";
}
}

How to find an array from parent array?

I am using below code to find an array inside parent array but it is not working that is retuning empty even though the specified key exits in the parent array
$cards_parent = $feedData['BetradarLivescoreData']['Sport']['Category']['Tournament']['Match'];
$cards = array();
foreach($cards_parent as $key => $card)
{
if ($key === 'Cards')
{
$cards[] = $cards_parent[$key];
break;
}
}
Do you know any array function that will search parent array for specified key and if found it will create an array starting from that key?
you want array_key_exists()
takes in a needle (string), then haystack (array) and returns true or false.
in one of the comments, there is a recursive solution that looks like it might be more like what you want. http://us2.php.net/manual/en/function.array-key-exists.php#94601
here you can use recursion:
function Recursor($arr)
{
if(is_array($arr))
{
foreach($arr as $k=>$v)
{
if($k == 'Cards')
{
$_GLOBAL['cards'][] = $card;
} else {
Recursor($arr[$k]);
}
}
}
}
$cards_parent = $feedData['BetradarLivescoreData']['Sport']['Category']['Tournament']['Match'];
$_GLOBAL['cards'] = array();
Recursor($cards_parent);
Could you please put a print_r($feedData) up? I ran the below code
<?php
$feedData = array('BetradarLivescoreData' => array('Sport' => array('Category' => array('Tournament' => array('Match' => array('Cards' => array('hellow','jwalk')))))));
$cards_parent = $feedData['BetradarLivescoreData']['Sport']['Category']['Tournament']['Match'];
$cards = array();
foreach($cards_parent as $key => $card)
{
if ($key === 'Cards')
{
$cards[] = $card;
break;
}
}
print_r($cards);
And it returned a populated array:
Array ( [0] => Array ( [0] => hellow [1] => jwalk ) )
So your code is correct, it may be that your array $feedData is not.

Get the first key for an element in PHP?

I'm trying to add an extra class tag if an element / value is the first one found in an array. The problem is, I don't really know what the key will be...
A minified example of the array
Array (
[0] => Array(
id => 1
name = Miller
)
[1] => Array(
id => 4
name = Miller
)
[2] => Array(
id => 2
name => Smith
[3] => Array(
id => 7
name => Jones
)
[4] => Array(
id => 9
name => Smith
)
)
So, if it's the first instance of "name", then I want to add a class.
I think I sort of understand what you're trying to do. You could loop through the array and check each name. Keep the names you've already created a class for in a separate array.
for each element in this array
if is in array 'done already' then: continue
else:
create the new class
add name to the 'done already' array
Sorry for the pseudo-code, but it explains it fairly well.
Edit: here's the code for it...
$done = array();
foreach ($array as $item) {
if (in_array($item['name'], $done)) continue;
// It's the first, do something
$done[] = $item['name'];
}
I assume you're looping through this array. So, a simple condition can be used:
$first = 0;
foreach ($arr as $value) {
if (!$first++) echo "first class!";
echo $value;
// The rest of process.
}
To get just the first value of an array, you can also use the old fashioned reset() and current() functions:
reset($arr);
$first = current($arr);
Animuson has it good. There a small addition if I might:
> $done = array();
> foreach ($array as $item) {
> if (in_array($item['name'], $done)) continue;
> // It's the first, do something
> $done[] = $item['name']; }
the in_array() will get slow very fast. Try something like:
$done = array();
foreach ($array as $item) {
$key = $item['name'];
if( !isset( $done[$key] )) {
...
}
$done[$key] = true;
}
btw. Too bad this site doesn't support comments for all users.

Categories