limiting array results returned - php

Hi I would like to limit the results returned depending on what type of product a user selects, $r[1] is the type of product with the array:
foreach($list as $r)
{
$row_color = ($row_count % 2) ? $color1 : $color2;
$size2 = $r[2];
echo "<tr>
<td id=\"id\"><span id=\"non_sorting_header\">" .$r[0]. "</span></td>
<td id=\"name\"><span id=\"non_sorting_header\">" .$r[1]. "</span></td>
<td id=\"speed\"><span id=\"sorting_header\">" .kMGTB2($size2). "</span></td>
<td id=\"download\"><span id=\"sorting_header\">" .$r[3]. " Gb<br />per month</span></td>
<td id=\"contract\"><span id=\"sorting_header\">1<br />month</span></td>
<td id=\"info\"><span id=\"non_sorting_header\">".$r[5]."</span></td>
<td id=\"buy\"><span id=\"non_sorting_header\">".$r[4]."<br />".$r[6]."</span></td>
</tr>";
$row_count++;
}
So if the user enters 'banana' then the function will find all instances within the array where $r[1] starts with the word 'banana' - start is key as it could be 'banana 1' 'banana 2' etc....
I cannot figure out a slick way to do this...any help would be appreciated!

You could use something like the following
function selectFromArray($prefix="", $productArray=array()) {
return array_filter($productArray,
create_function('$element',
'return (stripos($element[1],"'.$prefix.'") === 0); '));
}
Used like:
$list = selectFromArray("Banana", $list);
then proceed with the rest of your page.
That said, it's usually better to do this kind of filtering in your sql query with a WHERE clause

I'm not sure if Jonathan's answer is really the best way to do this.
First of all, create_function() is best avoided. Even without that, though, when using a separate function for it, you're still looping through the list twice. First you loop through the entire list to filter it, and then you loop through the filtered list to print the details. You can easily combine those two:
foreach ($list as $r)
{
if (stripos($r[1], $prefix) === 0) {
continue;
}
// as before...
}
If that condition gets any more complicated you can of course split it out into a separate function as well.

Related

Get First And Last Data From conditioned foreach loop

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>
}

PHP:Simple Dom Parser Find Nth Element Class Exist

I am using the PHP Simple DOM Parser for parsing the HTML Page, Now i am lacking in particular point of how to find the nth element class should be a particular class
For Example:
<table>
<tr>
<th class="h1">ONE</td>
<th class="h2">TWO</td>
<th class="h3">THREE</td>
</tr>
<tr>
<td class="one">Apple</td>
<td class="two">Orange</td>
<td class="null">N/A</td>
</tr>
<tr>
<td class="one">Apple</td>
<td class="null">N/A</td>
<td class="three">Banana</td>
</tr>
</table>
The table looks something like this , so i am traversing the table via tr
foreach ($demo->find("tr") as $val)
{
if(is_object($val->find('td.null', 0))
{
echo "FOUND";
}
}
But the above foreach loop returns "FOUND" if td.null exist.
But I need to find if 2nd element td class is null i need to return as TWO, If third td element class is null i need to return as Three
I hope so that you understand that what i am asking for , so please help me of how to find the nth element class is null
First, what I would do is also iterate each td's thru foreach. So that you'll be able to get which index number key it falls into. (Note that of course its indexing is zero based so it actually starts at 0).
Then inside the inner loop, just check if the class is null, then map it in the corresponding word 1 = one, 2 = two, etc...
Rough example:
$map = array(1 => 'one', 2 => 'two', 3 => 'three');
foreach ($demo->find('tr') as $tr) { // loop each table row
// then loop each td
foreach($tr->find('td') as $i => $td) { // indexing starts at zero
if($td->class == 'null') { // if its class is null
echo $map[$i+1]; // map it to its corresponding word equivalent
}
}
}
So in this case, this would output three and then two. Inside the second table row, the null lands on the third, inside the third row it lands into the second.
It's a pain to do things like that with simple html dom, if you switch to this one you will be able to do things like:
foreach($demo->find("td.null") as $td){
echo $td->index;
}
as well as lots of other jquery-style things that you would expect in a modern parsing lib.

How to put to style two foreach statements output PHP

How do I put the first foreach statement's output in one column in a table and the other foreach statement's output in another column. I tried something but it put it all in one column for some reason. Here is my code:
<table border="0" align="center">
<?php
foreach($anchors as $a) {
$text = $a->nodeValue;
$href = $a->getAttribute('href');
$i++;
if ($i > 16) {
if (strpos($text, "by owner") === false) {
if (strpos($text, "map") === false) {
echo "<tr><td><a href =' ".$href." '>".$text."</a><br/></td></tr>";
}
}
}
foreach($span as $s) {
echo "<tr><td>".$s->nodeValue."</td></tr>";
}
}
?>
</table>
<tr></tr> marks a row. <td></td> marks a column. To make 2 columns, use just one set of <tr> tags per iteration, with two sets of <td></td>s between them.
That said, what exactly is $span? Does it contain the same number of elements as $anchors, and you want to display one item from each per row? If so you'll need to restructure your code a bit. There are several ways to do this—here's a simple way:
<table border="0" align="center">
<?php
$i = 0;
foreach($anchors as $a) {
echo "<tr>";
$text = $a->nodeValue;
$href = $a->getAttribute('href');
if ($i >= 16) {
if (strpos($text, "by owner") === false) {
if (strpos($text, "map") === false) {
echo "<td><a href =' ".$href." '>".$text."</a><br/></td>";
}
}
} else {
echo "<td></td>"; #output a blank cell in the first column
}
echo "<td>" . $span[$i]->nodeValue . "</td>";
echo "</tr>";
++$i
}
?>
</table>
EDIT: It looks like your $span is a DOMNodeList object, not an array. I don't have experience with this, but it looks like you can use the DOMNodelist::item function to get the current item in the list (see http://php.net/manual/en/domnodelist.item.php):
echo "<td>" . $span->item($i)->nodeValue . "</td>";
So try changing the respective line in my answer to that.
It is hard without an idea of the data, but something like this perhaps:
// start a table
echo '<table>';
// for as long as there are elements in both span and anchors
for ($i=0; $i < $anchors->length && $i < $span->length; $i++) {
// start a new table row
echo '<tr>';
// get the current span and anchor
$a = $anchors->item($i);
$s = $span->item($i);
// print them
$text = $a->nodeValue;
$href = $a->getAttribute('href');
// col 1, number
echo '<td>'.$i.'</td>';
// col 2, anchor
echo '<td>'.$text.'</td>';
// col 3, span
echo '<td>'.$s->nodeValue.'</td>';
// close the table row
echo '</tr>';
}
// close the table
echo '</table>';
(code not tested) It is difficult to be more specific without the actual data.
This uses the 'current' and 'next' built in to php.
A few hints/remarks/sidenotes that may help you on the way:
- Note that I used single quotes cause they are much better for
performance (double quotes will be interpreted by php).
- Try to use as little loops (for, while, foreach) as possible. They are a powerfull
tool, but can drain memory and performance quickly!
- Only nest loops if you are working with multiple dimensions (array inside array),
which is not the case here (I think)
- Try to limit the number of nested blocks (if inside if inside if inside loop). I try to go never deeper then 2 levels (which is not an absolute rule off course, just a good standard). If not possible create a function.
- Comment your code! I have difficulty understanding your code (and I write PHP daily for a living), and I can imagine you will to in a couple of weeks. Commenting may look like a waste of time, but it will ease debugging a lot, and is a blessing when updating your (or someone elses) code later on!
EDIT:
I just noticed you are not working with a DOMNodeList and not an array, so I updated my code. Should work fine, and a lot cleaner code imo. Like I said, hard without seeing the data...

Php parsed html table and count specific <td> similar to another

This question follows another, just solved here
Now I want to do a different count, more difficult to figure out.
In my parsed HTML table, every rows contains two very similar, and consequential, 'td' (number 4 and 5):
<tr>
(1) <td class="tdClass" ....</td>
(2) <td class="tdClass" ....</td>
(3) <td class="tdClass" ....</td>
(4) <td class="tdClass" align="center" nowrap="">No</td>
(5) <td class="tdClass" align="center" nowrap="">No</td>
</tr>
The strings could be "No" in the first 'td' and "Yes' in the second one, and vice versa, both "Yes" or both "No".
I want to count how many 'td', of the 5 kind, contains "No"
By now I counted other 'td'-s by looping through them (see the selected answer for my previous question linked at the top) and selecting only ones matching a target string.
This could be done because those target strings appear only one time in each row.
In this case, instead, the target string ("No") is not unique for each row, because, as in the example above, could exist two times (in the 'td' 4 & 5) in the same 'tr'.
By that, I really don't know how to select only the second (5) 'td' for each row, which match the target string "No", and to exclude the (4) 'td' (which could match the same string) from the count.
Obviously, these two 'td'-s are under different column titles, but this couldn't be useful to distinguish them.
The only solution I have thought about, is to count the 'td' position from left, and to select only the 5th one, but I don't know if it's possible.
You will indeed have to update some parts. First you will want the 4th and 5th element, so you'll have to check for that (keep a counter or use a for loop). Secondly you don't need the break in this case, since it stops the loop.
Code:
<?php
$targetString = 'No';
$rows = $table->find('.trClass');
$count = 0;
foreach($rows as $row) {
$tds = $row->find('td');
for (i = 0; i < count($tds); $i++) {
// Check for the 4th and 5th element
if (($i === 3 || $i === 4) && $tds[$i]->innertext === $targetString) {
$count++;
}
}
}
Here I use a for loop instead of a foreach loop because I don't want to keep manually a counter. I can use the $i easily for this and just use it as an index as well.
Taking the code from your previous question, you should already have this:
$targetString = 'TARGET STRING';
$rows = $table->find('.trClass');
$count = 0;
foreach($rows as $row) {
foreach($row->find('td') as $td) {
if ($td->innertext === $targetString) {
$count++;
break;
}
}
}
Since you're already going through the td's, it would be quite simple to do what you said - "count the 'td' position from left, and to select only the 5th". As long as you know that it is definitely the fifth td you can do:
foreach($rows as $row) {
$tdcount = 0;
foreach($row->find('td') as $td) {
//...
//Bear in mind the first td will have tdcount=0, second tdcount=1 etc. so fifth:
if($tdcount === 4 && ( 'Yes'===$td->innertext || 'No'===$td->innertext) ) {
//do whatever you want with this td
}
$tdcount++;
}
}

Question about output formatting in PHP/XHTML

Is there a way to only print or output 10 elements per row inside a table in PHP from an indexed array with X number of elements of type int.
Maybe some function, I have not heard of?
Or some technique that's used by professionals or beginners alike.
I will embed some code for the TR and TD; however, I was just wondering if there is something I could use to only have 10 elements per row inside of my table.
[Disclaimer: I am new to PHP, and I am just learning, so please no flamers, it really hinders the learning process when one is trying to find solutions or information, thank you.]
You can use a counter in your loop to keep track of how many <td> elements you have generated in the current row:
echo "<tr>";
$i = 0;
foreach (...)
{
if ($i++ % 10 == 0)
{
echo "</tr><tr>";
}
echo "<td></td>";
}
echo "</tr>";
I like using: foreach, array_chunk, and implode to do this. It's better than having to futz with incrementing variables. I suggest you review array basics -- it's powerful stuff.
// here's an array with integers 1 to 50, for example:
$your_array = range(1,50);
// set how many you want in each row
$per_row = 10;
print "<table cellspacing='0' cellpadding='2' border='1'>\n";
Here's the code you can drop in to replace what you have:
foreach (array_chunk($your_array, $per_row) as $set_of_numbers) {
print "<tr><td>";
print implode('</td><td>',$set_of_numbers);
print "</td></tr>\n";
}
And finish with:
print "</table>\n";
That should get you the output you describe, a set of integers in a table, with 10 items per row. Now, if the size of $your_array has a remainder when divided by 10, you may need to pad those cells for looks, but that's secondary.
Output:
<table cellspacing='0' cellpadding='2' border='1'>
<tr><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td><td>9</td><td>10</td></tr>
<tr><td>11</td><td>12</td><td>13</td><td>14</td><td>15</td><td>16</td><td>17</td><td>18</td><td>19</td><td>20</td></tr>
<tr><td>21</td><td>22</td><td>23</td><td>24</td><td>25</td><td>26</td><td>27</td><td>28</td><td>29</td><td>30</td></tr>
<tr><td>31</td><td>32</td><td>33</td><td>34</td><td>35</td><td>36</td><td>37</td><td>38</td><td>39</td><td>40</td></tr>
<tr><td>41</td><td>42</td><td>43</td><td>44</td><td>45</td><td>46</td><td>47</td><td>48</td><td>49</td><td>50</td></tr>
</table>

Categories