Thanks in advance for looking.
I am trying to build some HTML using a foreach loop with a few layers of arrays.
Groups of data and groups of titles for that data are stored in sets of arrays.
In turn, those arrays of data are stored in an array ($titlegroups and datagroups).
The aim being to set up a nested loop, where each group of data and titles populate the relevant fields in some html.
Here is a full set of code (structure) of my attempt.
$a=1;
$b=2;
$c=3;
$d=4;
$titlesA=array('string1','string2');
$titlesB=array('string3','string4');
$dataA=array($a,$b);
$dataB=array($c,$d);
$titlegroups=array($titlesA,$titlesB);
$datagroups=array($dataA,$dataB);
$groups=array(array_combine($titlegroups, $datagroups));
$j=0;
foreach($groups as $titlesX => $dataX)
{
$j++;
echo'<div class="something">';
$i=0;
foreach(array_combine($titlesX, $dataX) as $title => $var)
{
$i++;
echo '
<li>'.$title.'</li><input name="'.$j.'x'.$i.'" value="'.$var.'" />
';
}
echo '</div>';
}
Checking it in ideone I get the error:
Warning: array_combine() expects parameter 1 to be array, integer
given in /home/0zw0mb/prog.php on line 26
Line 26 is:
foreach(array_combine($titlesX, $dataX) as $title => $var)
but $titlesX and $dataX should both be arrays?
If anyone can set me straight I'd appreciate it. Thanks.
You can't have arrays as keys, they are converted to strings. You logic required some changes and an additional sentinel variable ($idx), to tell when the code crosses one group to another.
array_merge was necessary due to the key requirements of arrays.
Check the below code:
$a=1;
$b=2;
$c=3;
$d=4;
$titlesA=array('string1','string2');
$titlesB=array('string3','string4');
$dataA=array($a,$b);
$dataB=array($c,$d);
$titlegroups=array_merge($titlesA,$titlesB);
$datagroups=array_merge($dataA,$dataB);
$items=array_combine($titlegroups, $datagroups);
$indexes = array(count($dataA), count($dataB));
$i = 0;
$j = 0;
$idx = $indexes[$j];
echo '<div class="something">';
foreach($items as $title => $var)
{
echo '
<li>'.$title.'</li><input name="'.$j.'x'.($i++).'" value="'.$var.'" />
';
$idx--;
if ($idx == 0) {
/* End of a group */
echo '</div>';
$idx = $indexes[++$j];
/* If there is another group, create new container */
if ($idx != null) {
echo '<div class="something">';
}
}
}
Related
Hello here i am with freaky problem,i wants the first data and last data from for-each loop. for that i have seen this answer. this would be really helpful but here my condition is really a little bit complex.
I have loop as following
<?php
$count = 0;
$length = count($myDataArray);
foreach ($myDataArray as $value) {
if($count >= 7)
{
//Some Data to Print
//this is first data for me
<tr >
<td><?=$myfinaldate?></td>
<td><?=$stockdata[1]?></td>
<td><?=$stockdata[2]?></td>
<td><?=$stockdata[3]?></td>
<td <?php if($count == 8)echo "style='background-color:#47ff77;'"; ?>><?=$stockdata[4]?></td>
<td><?=$stockdata[5]?></td>
<td><?php echo $mydate; ?></td>
</tr>
<?php
}
$count++;
}
Now How can i Get First And Last Data from loop ?
I imagine you could use your length attribute.
As you have the total of your array, just check
myDataArray[0] and myDataArray[$length-1] ?
To fetch first and last value of the array use the below function :
$array = $myDataArray;
$array_values = array_values($myDataArray);
// get the first value in the array
print $array_values[0]; // prints 'first item'
// get the last value in the array
print $array_values[count($array_values) - 1]; // prints 'last item'
You can use array_values to remove the keys of an array and replace them with indices. If you do this, you can access the specified fields directly. Like this you can check for your requirements on the array without looping over it, as shown in the if-conditions below:
$length = count($myDataArray);
$dataArrayValues = array_values($myDataArray);
$wantedFields = [];
if ($length >= 8) {
$wantedFields[] = $dataArrayValues[7];
if ($length > 8) {
$wantedFields[] = end($dataArrayValues);
}
}
Due to the conditions you will not print the 8th field twice in case it is the last field as well.
foreach ($wantedFields as $value) {
<tr>
... //Your previous code
</tr>
}
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Search for PHP array element containing string
I've created a mysql query that pulls through several products, all with the following information:
Product ID
Product Name
Product Price
and
Product Category
Further down the page, I've looped through these with a foreach and a few 'ifs' so it only displays those products where the name contains 'x' in one div and displays those products where the name contains 'y' in another div.
I'm struggling to count how many products are going to be in each div before I do the loop.
So essentially, what I'm asking is:
How do you count all elements in an array that satisfy a certain condition?
Added Code which shows the loop:
<div id="a">
<?php
$i = 1;
foreach ($products AS $product) {
if (strpos($product->name,'X') !== false) {
=$product->name
}
$i++;
} ?>
</div>
<div id="b">
$i = 1;
foreach ($products AS $product) {
if (strpos($product->name,'Y') !== false) {
=$product->name
}
$i++;
} ?>
</div>
I'd like to know how many of these are going to be in here before I actually do the loop.
Well, without seeing the code, so generally speaking, if you're going to split them anyway, you might as well do that up-front?
<?php
// getting all the results.
$products = $db->query('SELECT name FROM foo')->fetchAll();
$div1 = array_filter($products, function($product) {
// condition which makes a result belong to div1.
return substr('X', $product->name) !== false;
});
$div2 = array_filter($products, function($product) {
// condition which makes a result belong to div2.
return substr('Y', $product->name) !== false;
});
printf("%d elements in div1", count($div1));
printf("%d elements in div2", count($div2));
// then print the divs. No need for ifs here, because results are already filtered.
echo '<div id="a">' . PHP_EOL;
foreach( $div1 as $product ) {
echo $product->name;
}
echo '</div>';
echo '<div id="b">' . PHP_EOL;
foreach( $div2 as $product ) {
echo $product->name;
}
echo '</div>';
That being said: you should take notice of the comment which says "This is normally faster in SQL", because it is the more sane approach if you want to filter the values.
EDIT: Changed the name of the variables to adapt the variable names in the example code.
Use an array-filter: http://www.php.net/manual/en/function.array-filter.php
array array_filter ( array $input [, callable $callback = "" ] )
Iterates over each value in the input array passing them to the callback function. If the callback function returns true, the current value from input is returned into the result array. Array keys are preserved.
<?php
function odd($var)
{
// returns whether the input integer is odd
return($var & 1);
}
function even($var)
{
// returns whether the input integer is even
return(!($var & 1));
}
$array1 = array("a"=>1, "b"=>2, "c"=>3, "d"=>4, "e"=>5);
$array2 = array(6, 7, 8, 9, 10, 11, 12);
echo "Odd :\n";
print_r(array_filter($array1, "odd"));
echo "Even:\n";
print_r(array_filter($array2, "even"));
?>
But be aware, this is a loop though, and your the SQL query will be faster.
I am working with SimplePie and I cannot figure out how to output the count, or the key values for the loop.
Shouldn't this
<?php foreach ($feed->get_items() as $item): ?>
<?php
$i = key($item);
echo $i;
?>
<?php endforeach; ?>
, or this
<?php foreach ($feed->get_items() as $item): ?>
<?php
$i = count($item);
echo $i;
?>
<?php endforeach; ?>
be outputting a unique number for each?
uniqid() Doesn't work in this case, because I am running the loop twice on the page and trying to match up one list of elements with another based on ID.
A single argument used with as is interpreted as a variable in which to store the value, not the key. If you want the key, you need to use => in a manner like the following:
foreach ($feed->get_items() as $key => $item):
echo $key;
endforeach
As a sidenote, you're using key() and count() on an item in the array, rather than the array as a whole, which is invalid. As far as I'm aware, there's no guarantee that key() will work as you expect even if applied to the whole array. It's meant for loops where you control the iteration, as with next.
To get the 'count' in a foreach you would need an extra variable. Getting the key is easy and the same if the array is indexed in order instead of associative. Here is an example including both:
$array = array(
'foo' => 'bar'
);
$i = 0;
foreach ($array as $key => $value)
{
/*
code where $i is the 'count' (index) and $key is the associative $key.
*/
/* $i == 0 */
/* $key == 'foo' */
/* $value == 'bar' */
$i++;
}
key($item) that you're using above doesn't work because you're trying to get the key of a value that no longer is associated with the original array.
count($item) is the count of a subarray $item.
you can use get_id() method
like :
foreach ($feed->get_items() as $item)
{
$prev_ids = array('guid1', 'guid2', 'guid3', 'guid4');
if (in_array($item->get_id(true), $prev_ids))
{
echo "This item is already stored.";
}
else
{
echo "This is a new item!";
}
}
Error I'm receiving Invalid argument supplied for foreach()
The offending portions is this:
foreach($subs[$id] as $id2 => $data2)
Strange cause I'm using the same construct elsewhere and it works fine.. I'm using it to generate sub-categories and it works but I want to get rid of the error
This is more context
foreach($parents as $id => $data)
{
if($x == 0)
{
$html .= "<tr width='25%' class='row2'>";
}
$shtml = "";
$i = 0;
***foreach($subs[$id] as $id2 => $data2)***
{
$i++;
if($i == 15)
{
$shtml .= $this->ipsclass->compiled_templates[ 'skin_businesses' ]->portal_categories_sub_row( $id2, $data2['cat_name'], 1 ) . "";
break;
}
else
$shtml .= $this->ipsclass->compiled_templates[ 'skin_businesses' ]->portal_categories_sub_row( $id2, $data2['cat_name'], 0 ) . "";
}
It may be that $subs[$id] is not consistently an array. That is, $subs[0] may be an array, but $subs[1] is a scalar.
Try casting it to be an array:
foreach((array)$subs[$id] as $id2 => $data2)
If $subs[1] is a scalar, then casting it forms an ephemeral array of one element for purposes of iterating over it.
The variable that you pass to the loop is probably not an array. Try to debug your code to find out where it being assigned an value just before being fed into the loop.
If you assinged a single value to that variable somewhere, assign it like this:
$subs[1] = array('somevalue');
PHP is a dynamically typed language but knowing what type a variable has at any given moment is still very important.
I'm trying, but I'm stucked with the logic... so, I have this:
$max_items=10;
echo '<table>';
echo '<tr>';
foreach ($feed->get_items(0, $max_items) as $item):
echo '<td>';
echo $some_value;
echo '</td>';
endforeach;
echo '</tr>';
echo '</table>';
I want to show the results like this:
[1][2]
[3][4]
[5][6]
[7][8]
[9][10]
I have to use a while statement? A for loop? Inside or outside the foreach code?
I really don't get it...
Thanks for any kind of help
Here's a very simple example of how to do this sort of HTML building.
<?php
$data = range( 'a', 'z' );
$numCols = 2;
echo "<table>\n";
echo "\t<tr>\n";
foreach( $data as $i => $item )
{
if ( $i != 0 && $i++ % $numCols == 0 )
{
echo "\t</tr>\n\t<tr>\n";
}
echo "\t\t<td>$item</td>\n";
}
echo "\t</tr>\n";
echo '</table>';
This way, you can change $numCols to be 3 or 4 (or any number) and always see that number of columns in the output, and it does so without using an nested loop.
Take a look at this link to Displaying Recent Posts On a Non-WordPress Page. I think what you may be looking for is a way to loop over the objects get methods. For that you will need a nested loop and some sort of reflection.
I was just recently working with SimplePie on the February release of Cogenuity so this is still fresh in my mind.
Your $some_value variable never gets initialized.
The $item object will have such methods as get_permalink(), get_title(), get_description(), and get_date()