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
Related
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
i want to calculate two operations with the help of loop. They are already working and providing result i need. But i want them to look more like coding. So if anybody can help them with the help of for in php
for($i=0;i<something;$i++){
$temp_calc = ;
}
here are two statements.
In first statement length of array is 9.
In second statement length of array is 12.
both statements to be solved in different for loop as they are totally different questions.
$temp_calc = 10*$temp_array[0]+9*$temp_array[1]+8*$temp_array[2]+7*$temp_array[3]+6*$temp_array[4]+5*$temp_array[5]+4*$temp_array[6]+3*$temp_array[7]+2*$temp_array[8];
$temp_calc = 1*$temp_array[0]+3*$temp_array[1]+1*$temp_array[2]+3*$temp_array[3]+1*$temp_array[4]+3*$temp_array[5]+1*$temp_array[6]+3*$temp_array[7]+1*$temp_array[8]+3*$temp_array[9]+1*$temp_array[10]+3*$temp_array[11];
Thanks in advance
It will be a little simpler to use a foreach loop rather than a for loop. If you specifically need to use a for loop because it is a requirement of an assignment, you can check the PHP documentation. There are some examples there of using a for loop to loop over an array. This is a common and basic control structure and it will be more valuable for you to really understand how to use it. The more important part is what goes on inside the loop. There are multiple ways to do this, but here are some basic examples.
First one:
// initialize multiplier and result outside the loop
$multiplier = 10;
$result = 0;
// loop over the values
foreach ($temp_array as $value) {
// add the value * multiplier to the result and decrement the multiplier
$result += $value * $multiplier--;
}
Second one
// initialize multiplier and result outside the loop
$multiplier = 1;
$result = 0;
// loop over the values
foreach ($temp_array as $value) {
// add the value * multiplier to the result
$result += $value * $multiplier;
// switch the multiplier to the alternating value
if ($multiplier == 1) {
$multiplier = 3;
} else {
$multiplier = 1;
}
// The switch can be done more simply using a ternary operator like this:
// $multiplier = $multiplier == 1 ? 3 : 1;
}
for both issues:
$temp_array = array(2,2,2,2,2,2,2,2,2);//sample
function calc_1($temp_array){//first
$total=0;
$count = count($temp_array)+1;
foreach($temp_array as $value){
$total += $count*$value;
$count-=1;
}
return $total;
}
function calc_2($temp_array){//second
$total=0;
foreach($temp_array as $k=>$value){
$total += ($k%2==0) ? 1*$value : 3*$value;//when is even or odd
}
return $total;
}
var_dump(calc_1($temp_array));//resp1
var_dump(calc_2($temp_array));//resp2
If your array is called $myArray, then:
/*Since I can't know what the sequence of the values are that you
are multiplying, and because you might need other sequences in the
future, a function was developed that chooses which sequence you
want to multiply.*/
function findSomeValues($arraySize)
{
switch ($arraySize) {
case 9:
{
$someValues = array(10,9,8,7,4,5,4,3,2);
}
break;
case 12:
{
$someValues = array(1,3,1,3,1,3,1,3,1,3,1,3);
}
break;
default:
$someValues = array();
}
return $someValues;
}
/*This following function then finds how big your array is, looks
for a sequence stored in the findSomeValues function. If a sequence
exist for that array size (in this case if you have an array either
9 or 12 elements long), the result will be calculated and echoed. If
the sequence was not found, an error message would be echoed.*/
function multiplyValues($myArray) {
$result = 0;
$arraySize = count($myArray);//obtaining array size
$someValues = findSomeValues($arraySize);//obtaining sequence to multiply with
if (count($someValues)>0)
{
for($i=0;i<$arraySize;$i++){
$result += $myArray[i]*$someValues[i];
}
echo "result = ".$result."<br>";//result message
}
else
{
echo "you are missing some values<br>";//error message
}
}
Let me know if that worked for you.
Alternative:
If you prefer something a bit simpler:
//this array holds the sequences you have saved:
$sequenceArray = array(
9 => array(10,9,8,7,4,5,4,3,2),
12 => array(1,3,1,3,1,3,1,3,1,3,1,3)
);
//this function does the multiplication:
function multiplyValues($myArray)
{
$arraySize = count($myArray);
for($i=0;i<$arraySize;$i++){
$result += $myArray[i]*$sequenceArray[i];
}
echo "result = ".$result."<br>";//result message
}
For your result
$temp_calc = 10*$temp_array[0]+9*$temp_array[1]+8*$temp_array[2]+7*$temp_array[3]+6*$temp_array[4]+5*$temp_array[5]+4*$temp_array[6]+3*$temp_array[7]+2*$temp_array[8];
You should have for loop as following. It will run the loop till 8th index of your temp_array and multiply each index value with $i and sum up in a variable $temp_calc_1.
<?php
$temp_calc_1 = 0;
for($i=0;$i<9;$i++){
$temp_calc_1 = $temp_calc_1 + ( 10-$i)*$temp_array[$i] ;
}
For your second result
$temp_calc = 1*$temp_array[0]+3*$temp_array[1]+1*$temp_array[2]+3*$temp_array[3]+1*$temp_array[4]+3*$temp_array[5]+1*$temp_array[6]+3*$temp_array[7]+1*$temp_array[8]+3*$temp_array[9]+1*$temp_array[10]+3*$temp_array[11];
The above should be converted to the following loop, this will run loop till your 12th index of temparrayand do the calculation. This time it will multiply each index value of temparray by either 1 and 3. So first time it will multiply with 1 and next time with 3 and so on
//
$temp_calc_2 = 0;
for($i=0;$i<12;$i++){
$j = $i%2?3:1;
$temp_calc_2 = $temp_calc_2 + $j*$temp_array[$i] ;
}
?>
I'm trying to remove an object from an array if one of his properties is null or empty, this is the code.
The array has been sorted using this function:
function sortArray($c1, $c2)
{
return ($c1->propertyToCheck < $c2->propertyToCheck);
}
In case it changes anything.
$myArray = array();
...
// Add values to the array here
...
usort($myArray,"sortArray");
for($i = 0; $i < count($myArray ); $i++)
{
if(empty($myArray[$i]->propertyToCheck))
{
unset($myArray[$i]);
// var_dump($myArray[$i]) returns NULL
}
}
echo json_encode($myArray);
// Returns the entire array, even with the values that shouldn't be there.
The code is inside a function but the array is created inside said function.
I'm using echo json_encode($myArray) to send the value back in AJAX, but the array sent is the entire array with every object inside it.
The count($myArray) is the "problem".
Once the unset() is "reached" there is one element less in the array and therefore the next call to count($myArray) will return n-1 of the previous iteration -> your loop doesn't get to the end of the array.
You have at least three choices (in ascending order of my preference)
a)
$maxIdx = count($myArray);
for($i = 0; $i < $maxIdx; $i++) {
b)
foreach( $myArray as $key=>$obj ) {
if(empty($obj->propertyToCheck)) {
unset($myArray[$key]);
c)
$myArray = array_filter(
$myArray,
function($e) {
return !empty($e->propertyToCheck);
}
);
(...and many more)
see also: http://docs.php.net/array_filter
I asked a similar question earlier but I couldn't get a clear answer to my issue. I have a function "isParent" that gets 2 pieces of data. Each 1 of the 2 gets a string separating each value with a , or it just gets a plain int and then checks if the first value given is a parent of the second.
I pull the 2 bits of data in and explode them but when I go through my nested for loop and try to test
$toss = $arr1[$i];
print_r($toss);
It comes up blank. I have no idea what the issue is: Here is the full code of the function...
function isParent($parent, $child)
{
$parentArr = explode(',', $parent);
$childArr = explode(',',$child);
//Explode by Comma here. If array length of EITHER parentArr or childArr > 1 Then throw to an Else
if(count($parentArr) <= 1 && count($childArr) <= 1) //If explode of either is > 1 then ELSE
{
$loop = get_highest_slot(15);
for($i = $loop; $i > 0; $i--)
{
$temp = get_membership_from_slot($i,'id_parent','id_child');
if($temp['id_parent'] == $parent && $temp['id_child'] == $child)
{
return 1;
}
}
}
else //set up a for loop in here so that you traverse each parentArr value and for each iteration check all child values
{
$i = count($parentArr);
$c = count($childArr);
for(;$i >=0;$i--) //Loop through every parent
{
for(;$c >=0;$c--)
{
echo '<br>$i = ';
print_r($i);
echo '<br><br>Parent Arr at $i:';
$toss = $parentArr[$i];
echo $toss;
echo '<br>';
print_r($childArr);
echo '<br><br>';
if(isParent($parentArr[$i],$childArr[$c])) //THIS CAUSES AN INFINITE YES! Learn how to pull an array from slot
{
return 1;
}
}
}
}
return 0;
}
You are missing some code for the slot procedures. Apart from that, you probably need to use a different variable for the inner for loop. because $c will be 0 after the first iteration of $i.
Thanks for the help! The issue was in the recursive call back to the top of the function. It was tossed empty slots and when comparing 2 empty slots it returned a false positive. A quick !empty() check fixed it.
There is an array :
$ret = array();
... query execution
$ret['cnt'] = $this->db->num_rows(); // total number of database records
$i = 0;
while ( $this->db->next_record() ) { // fetching database records
$ret[$i]["user_id"] = $this->db->f('user_id') ;
$ret[$i]["user_login"] = stripslashes($this->db->f('user_login'));
$i++;
}
Now I want to remove from this array the element whose "user_id" is equal to a particular value :
if ($ret['cnt'] > 0) {
for ($i=0; $i<$ret['cnt']; $i++) {
if ($ret[$i]['user_id'] == $_SESSION[CODE_USER]) {
unset($ret[$i]);
break;
}
}
}
After printing the array I noticed that the element 0 is not in the array , this is what I am expecting. The only problem is now how to rearrange the array elements so that it will be compact again without any hole in its elements because the element 0 is not present ?
Use array_values:
$ret = array_values($ret);
http://php.net/manual/en/function.array-values.php
Or instead of using the 0th index. You could just grab the first element with reset.
http://php.net/manual/en/function.reset.php
array_values is probably the simplest way to reset keys.
if ($ret['cnt'] > 0) {
for ($i=0; $i<$ret['cnt']; $i++) {
if ($ret[$i]['user_id'] == $_SESSION[CODE_USER]) {
$ret = array_slice($ret,$i,1);
break;
}
}
}
array_slice will also strip away a section of the array and re-index as necessary.