How to remove an all the elements in an array through iteration - php

I have an array $scripts_stack = []; that holds arrays:
$array_item = array('script' => $file_parts, 'handle' => $file_name, 'src' => $url);
array_push($scripts_stack, $array_item);
<?php
for ($i = 0; $i < sizeof($scripts_stack); $i++) {
$child_array = $scripts_stack[$i];
if (is_array($child_array)) {
// Do things with $child_array,
// then remove the child array from $scripts_stack when done with (BELOW)
unset($scripts_stack[$i]);
}
}
echo "Array Size : " . (sizeof($scripts_stack)); // AT THE END
However, my attemts only remove half the elements. No matter what I try, it's only half the items that get removed. sizeof($scripts_stack) is always half the size of what it was at the start.
I'm expecting that it would be empty // AT THE END
Why is it that I only get half the elements in the array removed?
Thank you all in advance.

As mentioned in other answers, $i increments but the sizeof() the array shrinks. foreach() is probably the most flexible looping for arrays as it exposes the actual key (instead of hoping it starts at 0 and increments by 1) and the value:
foreach ($scripts_stack as $key => $child_array) {
if (is_array($child_array)) {
// Do things with $child_array,
// then remove the child array from $scripts_stack when done with (BELOW)
unset($scripts_stack[$key]);
}
}

Just FYI, the way you're doing it with for almost works. You just need to establish the count before the loop definition, rather than recounting in the continuation condition.
$count = sizeof($scripts_stack);
for ($i = 0; $i < $count; $i++) { // ...
Still, I think it would be better to just use a different type of loop as shown in the other answers. I'd personally go for foreach since it should always iterate every element even if some indexes aren't present. (With the way you're building the array, it looks like the indexes should always be sequential, though.)
Another possibility is to shift elements off of the array rather than explicitly unsetting them.
while ($child_array = array_shift($scripts_stack)) {
// Do things with $child_array,
}
This will definitely remove every element from the array, though. It looks like $child_array should always be an array, so the is_array($child_array) may not be necessary, but if there's more to it that we're not seeing here, and there are some non-array elements that you need to keep, then this won't work.

You advanced $i while the array is getting shrinked, but in the same time you jump over items in your array.
The first loop is where $i == 0, and then when you removed item 0 in your array, the item that was in the second place has moved to the first place, and your $i == (so you will not remove the item in the current first place, and so on.
What you can do is use while instead of for loop:
<?php
$i = 0;
while ($i < sizeof($scripts_stack)) {
$child_array = $scripts_stack[$i];
if (is_array($child_array)) {
// Do things with $child_array,
// then remove the child array from $scripts_stack when done with (BELOW)
unset($scripts_stack[$i]);
} else {
$i++;
}
}
echo "Array Size : " . (sizeof($scripts_stack)); // AT THE END

May be you can use this script.It's not tested.
foreach($array as $key => $value ) {
unset($array[$key]);
echo $value." element is deleted from your array</br>";
}
I hope , it will help you.

The problem root is in comparing $i with sizeof($scripts_stack). Every step further sizeof($scripts_stack) becomes lower (it calculates at every step) and $i becomes higher.
The workaround may look like this:
<?php
$scripts_stack = [];
$array_item = array('script' => 1, 'handle' => 2, 'src' => 3);
array_push($scripts_stack, $array_item);
array_push($scripts_stack, $array_item);
array_push($scripts_stack, $array_item);
array_push($scripts_stack, $array_item);
array_push($scripts_stack, $array_item);
while (sizeof($scripts_stack) > 0) {
$child_array = array_shift($scripts_stack);
if (is_array($child_array)) {
// Do things with $child_array,
// then remove the child array from $scripts_stack when done with (BELOW)
}
}
echo "Array Size : " . (sizeof($scripts_stack)); // AT THE END
https://3v4l.org/N2p3v

Related

Finding entry in array and putting it first or swapping with the first array entry

I have a PHP array full of arrays and what I want to do is search through this array for the chosen entry and swap it with the first entry in the array if that makes sense...
So for my example below I have chosen Penny so I would like her to either go before Bob or swap places with Bob.
My array looks like this:
$people = array(
array('Bob', 'Wilson'),
array('Jill', 'Thompson'),
array('Penny', 'Smith'),
array('Hugh', 'Carr')
);
I have tried using array_search but I don't think I am doing it correctly.
for ($i = count($array) - 1; $i > 0; $i--) {
if ($array[$i][0] == $first_name) { // Or by whatever you want to search? in_array...?
$searched_array = array_splice($array, $i, 1);
array_unshift($array, $searched_array[0]);
}
}
This is for prepending. If you want to swap, see the answer of #IAmNotProcrastinating
function swap (&$ary,$fromIndex,$toIndex=0)
{
$temp=$ary[$toIndex];
$ary[$toIndex]=$ary[$fromIndex];
$ary[$fromIndex]=$temp;
}
foreach ($elements as $key => $element) {
/* do the search, get the $key and swap */
}

Removing elements from an array in php [duplicate]

This question already has answers here:
Removing a value from a PHP Array
(3 answers)
Closed 8 years ago.
I have an array that looks like this
$hours_worked = array('23',0,'24',0)
What want to do is to loop through the array and remove the element that contains 0
What I have so far is:
for($i = 0; $i < count($hours_worked); $i++)
{
if($hours_worked[$i] === 0 )
{
unset($hours_worked[$i]);
}
}
However the result I get is $hours_worked = array(23,24,0). I.e. it does not remove the final element from the array. Any ideas?
The problem with this code is that you are calculating count($hours_worked) on each iteration; once you remove an item the count will decrease, which means that for each item removed the loop will terminate before seeing one item at the end of the array. So an immediate way to fix it would be to pull the count out of the loop:
$count = count($hours_worked);
for($i = 0; $i < $count; $i++) {
// ...
}
That said, the code can be further improved. For one you should always use foreach instead of for -- this makes the code work on all arrays instead of just numerically indexed ones, and is also immune to counting problems:
foreach ($hours_worked as $key => $value) {
if ($value === 0) unset($hours_worked[$key]);
}
You might also want to use array_diff for this kind of work because it's an easy one-liner:
$hours_worked = array('23',0,'24',0);
$hours_worked = array_diff($hours_worked, array(0)); // removes the zeroes
If you choose to do this, be aware of how array_diff compares items:
Two elements are considered equal if and only if (string) $elem1 ===
(string) $elem2. In words: when the string representation is the
same.
Try foreach loops instead
$new_array = array();
foreach($hours_worked as $hour) {
if($hour != '0') {
$new_array[] = $hour;
}
}
// $new_array should contain array(23, 24)

Remove Array value

[0] => LR-153-TKW
[1] => Klaten
[2] => Rectangular
[3] => 12x135x97
I have an array looking like this. and I want to completely remove 12x135x97 to the mother array so how would i do this?
You can use unset($arr[3]);. It will delete that array index. Whenever you want to delete an array value, you can use PHP unset() method.
As you were asked into your comment:
basically i just want to remove all index that have "X**X" this pattern digit 'x' digit
Here is the code that you can use:
$arr = array("LR-153-TKW", "Klaten", "Rectangular", "12x135x97", "xxxx");
$pattern_matched_array = preg_grep("/^[0-9]+x[0-9]+x[0-9]*/", $arr);
if(count($pattern_matched_array) > 0)
{
foreach($pattern_matched_array as $key => $value)
{
unset($arr[$key]);
}
}
print_r($arr);
PHP has unset() function. You can use it for deleting a variable or index of array.
unset($your_var[3]);
See http://php.net/manual/en/function.unset.php
You have many options:
if you know the array key then you can do this
unset($arrayName[3]);
or if it's always at the end of your array
array_pop($arrayName);
this will remove the last value out of your array
Use unset, to find it you can do this:
for($i = 0; $i < count($array); $i++){
if($i == "12x135x97"){
unset($array[i]);
break;
}
}
Unless you know the key, in which case you can do:
unset($array[3]);
its not the most time efficient if you array is thousands of items long, but for this job it will suffice.
To turn it into a method, would make for better coding.
function removeItem($item){
for($i = 0; $i < count($array); $i++){
if($i == $item){
unset($array[i]);
break;
}
}
return $array;
}
and call it like:
removeItem("12x135x97");

php how to loop through array until condition is met?

I have a database table with images that I need to display. In my view, I'd like to display UP TO 10 images for each result called up. I have set up an array with the 20 images that are available as a maximum for each result (some results will only have a few images, or even none at all). So I need a loop that tests to see if the array value is empty and if it is, to move onto the next value, until it gets 10 results, or it gets to the end of the array.
What I'm thinking I need to do is build myself a 2nd array out of the results of the test, and then use that array to execute a regular loop to display my images. Something like
<?php
$p=array($img1, $img2.....$img20);
for($i=0; $i<= count($p); $i++) {
if(!empty($i[$p])) {
...code
}
}
?>
How do I tell it to store the array values that aren't empty into a new array?
you could do something like:
$imgs = array(); $imgs_count = 0;
foreach ( $p as $img ) {
if ( !empty($img) ) {
$imgs[] = $img;
$imgs_count++;
}
if ( $imgs_count === 10 ) break;
}
You can simply call array_filter() to get only the non-empty elements from the array. array_filter() can take a callback function to determine what to remove, but in this case empty() will evaluate as FALSE and no callback is needed. Any value that evaluates empty() == TRUE will simply be removed.
$p=array($img1, $img2.....$img20);
$nonempty = array_filter($p);
// $nonempty contains only the non-empty elements.
// Now dow something with the non-empty array:
foreach ($nonempty as $value) {
something();
}
// Or use the first 10 values of $nonempty
// I don't like this solution much....
$i = 0;
foreach ($nonempty as $key=>$value) {
// do something with $nonempty[$key];
$i++;
if ($i >= 10) break;
}
// OR, it could be done with array_values() to make sequential array keys:
// This is a little nicer...
$nonempty = array_values($nonempty);
for ($i = 0; $i<10; $i++) {
// Bail out if we already read to the end...
if (!isset($nonempty[$i]) break;
// do something with $nonempty[$i]
}
$new_array[] = $p[$i];
Will store $p[$i] into the next element of $new_array (a.k.a array_push()).
Have you thought about limiting your results in the sql query?
select * from image where img != '' limit 10
This way you are always given up to 10 results that are not empty.
A ẁhile loop might be what you're looking for http://php.net/manual/en/control-structures.while.php

how to skip elements in foreach loop

I want to skip some records in a foreach loop.
For example, there are 68 records in the loop. How can I skip 20 records and start from record #21?
Five solutions come to mind:
Double addressing via array_keys
The problem with for loops is that the keys may be strings or not continues numbers therefore you must use "double addressing" (or "table lookup", call it whatever you want) and access the array via an array of it's keys.
// Initialize 25 items
$array = range( 1, 25, 1);
// You need to get array keys because it may be associative array
// Or it it will contain keys 0,1,2,5,6...
// If you have indexes staring from zero and continuous (eg. from db->fetch_all)
// you can just omit this
$keys = array_keys($array);
for( $i = 21; $i < 25; $i++){
echo $array[ $keys[ $i]] . "\n";
// echo $array[$i] . "\n"; // with continuous numeric keys
}
Skipping records with foreach
I don't believe that this is a good way to do this (except the case that you have LARGE arrays and slicing it or generating array of keys would use large amount of memory, which 68 is definitively not), but maybe it'll work: :)
$i = 0;
foreach( $array as $key => $item){
if( $i++ < 21){
continue;
}
echo $item . "\n";
}
Using array slice to get sub part or array
Just get piece of array and use it in normal foreach loop.
$sub = array_slice( $array, 21, null, true);
foreach( $sub as $key => $item){
echo $item . "\n";
}
Using next()
If you could set up internal array pointer to 21 (let's say in previous foreach loop with break inside, $array[21] doesn't work, I've checked :P) you could do this (won't work if data in array === false):
while( ($row = next( $array)) !== false){
echo $row;
}
btw: I like hakre's answer most.
Using ArrayIterator
Probably studying documentation is the best comment for this one.
// Initialize array iterator
$obj = new ArrayIterator( $array);
$obj->seek(21); // Set to right position
while( $obj->valid()){ // Whether we do have valid offset right now
echo $obj->current() . "\n";
$obj->next(); // Switch to next object
}
$i = 0;
foreach ($query)
{
if ($i++ < 20) continue;
/* php code to execute if record 21+ */
}
if want to skipped some index then make an array with skipped index and check by in_array function inside the foreach loop if match then it will be skip.
Example:
//you have an array like that
$data = array(
'1' => 'Hello world',
'2' => 'Hello world2',
'3' => 'Hello world3',
'4' => 'Hello world4',
'5' => 'Hello world5',// you want to skip this
'6' => 'Hello world6',// you want to skip this
'7' => 'Hello world7',
'8' => 'Hello world8',
'9' => 'Hello world8',
'10' => 'Hello world8',//you want to skip this
);
//Ok Now wi make an array which contain the index wich have to skipped
$skipped = array('5', '6', '10');
foreach($data as $key => $value){
if(in_array($key, $skipped)){
continue;
}
//do your stuf
}
You have not told what "records" actually is, so as I don't know, I assume there is a RecordIterator available (if not, it is likely that there is some other fitting iterator available):
$recordsIterator = new RecordIterator($records);
$limited = new LimitIterator($recordsIterator, 20);
foreach($limited as $record)
{
...
}
The answer here is to use foreach with a LimitIterator.
See as well: How to start a foreach loop at a specific index in PHP
I'm not sure why you would be using a foreach for this goal, and without your code it's hard to say whether this is the best approach. But, assuming there is a good reason to use it, here's the smallest version I can think of off the top of my head:
$count = 0;
foreach( $someArray as $index => $value ){
if( $count++ < 20 ){
continue;
}
// rest of foreach loop goes here
}
The continue causes the foreach to skip back to the beginning and move on to the next element in the array. It's extremely useful for disregarding parts of an array which you don't want to be processed in a foreach loop.
for($i = 20; $i <= 68; $i++){
//do stuff
}
This is better than a foreach loop because it only loops over the elements you want.
Ask if you have any questions
array.forEach(function(element,index){
if(index >= 21){
//Do Something
}
});
Element would be the current value of index.
Index increases with each turn through the loop.
IE 0,1,2,3,4,5;
array[index];

Categories