I need a counter within a counter - php

I have searched for this, can't find it and it should be simple, but now I'm crosseyed. Forgive me - I've only been at this for a few months.
I need a counter within a counter in php, such that I pair $Id1 with $Id2, then $Id3, then $Id4, etc. for a single loop through, and then for the second loop pair $Id2 with $Id3, then $Id4, then $Id5 etc. I get the Ids from a sql query, then I use both of them to run a calculation of their relationship, but first I just need the structure to run these two loops, one within the other. Thanks for any help and your patience.
Edited to add what I have so far:
$collection = [];
$sql = 'SELECT id, name FROM table';
$result = mysql_query($sql);
while($row = mysql_fetch_assoc($result))
{
$collection[] = $row;
}
$ct = count($collection);
for ($i = 0; $i < $ct; $i++)
{
$Id1 = $collection[$i]['id'];
for ($j = 0; $j < $ct; $j++)
{
$Id2 = $collection[$j]['id'];
if($Id1 != $Id2){
echo 'IDs: ' . $Id1 . ' ' . $Id2 . '<br>';
}
}
}
}

If you fetch the IDs from your query into an array like this: $ids = [1,2,3,4,5,6,7,8];, you can get a list of pairs using array_chunk, then shifting off the first element, and repeating this process until the array is empty.
while ($ids) { // repeat until empty
$pairs = array_chunk($ids, 2); // split into pairs
foreach ($pairs as $pair) {
if (count($pair) == 2) { // verify that you have a pair (last element will
// have only one item when count($ids) is odd)
var_dump($pair); // do something with your pair of IDs
}
}
$remove_first = array_shift($ids); // shift off the first ID
}
Please note that using array_shift like this will destroy your input array, so if you need to do something else with it as well, make a copy of it before using this approach.

Related

Print all values of array with a nested index in PHP without a loop

I have an array which has nested String that I want to output without a loop.
Here is the array:
$field_my_array[0]['string_term']->name = "First";
$field_my_array[1]['string_term']->name = "Second";
$field_my_array[2]['string_term']->name = "Third";
$field_my_array[3]['string_term']->name = "Forth";
$field_my_array[4]['string_term']->name = "Fifth";
I want to output this as
First, Second, Third, Forth, Fifth
This is what I tried (but it's in loop)
for ($ctr = 0; $ctr < count($field_my_array); $ctr ++) {
print $field_my_array[$ctr]['string_term']->name;
if ($ctr < count($field_my_array) -1) {print ", ";}
}
I'd be inclined to break this down into two parts:
Convert the array into a simplified version that just contains the values you want to concatenate. For that, you can use array_map() (https://www.php.net/manual/en/function.array-map.php).
Join the elements of the array without an extra comma on the end. The perfect use case for implode() (https://www.php.net/manual/en/function.implode.php).
Example:
echo implode(', ', array_map(function($item) {
return $item['string_term']->name;
}, $field_my_array));
I am not sure what you're trying to achieve. If you don't want to loop, then you have to manually write like this:
echo $field_my_array[0]['string_term']->name;
echo ", ";
echo $field_my_array[1]['string_term']->name;
...
and so on. Looping is a fundamental programming construct that allows us to automate with a simple count.
for ($ctr = 0; $ctr < count($field_my_array); $ctr ++) {
print $field_my_array[$ctr]['string_term']->name;
if ($ctr < count($field_my_array) -1) {print ", ";}
}
A better one would be this:
$field_my_array[0]['string_term']->name = "First";
$field_my_array[1]['string_term']->name = "Second";
$field_my_array[2]['string_term']->name = "Third";
$field_my_array[3]['string_term']->name = "Forth";
$field_my_array[4]['string_term']->name = "Fifth";
$names = array();
for ($ctr = 0; $ctr < count($field_my_array); $ctr ++) {
$names[] = $field_my_array[$ctr]['string_term']->name;
}
// this creates a string with a comma between items from array
$full_text = implode(', ',$names);
echo $full_text ;
You can use array_merge_recursive with implode
$c = array_merge_recursive(...$field_my_array);
echo implode(',', $c['string_term']['name']);
Live DEMO https://3v4l.org/GdhM5

How to iterate multi dimensional array and calculate sum for each row in php?

i have this array which i retrieved data from my database and put it in an array :
$query = "select * from caseunder";
$result=mysql_query($query) or die('Error, insert query failed');
$array[] = array();
$numrows=mysql_num_rows($result);
WHILE ($i < $numrows){
$allergies =mysql_result($result, $i, "allergies");
$vege = mysql_result($result,$i, "vege");
$age = mysql_result($result, $i, "age");
$bmi =mysql_result($result, $i, "bmi");
$solution = mysql_result($result,$i, "solution");
$bmi2 = $_POST['weight'] / (($_POST['height']/100)*($_POST['height']/100));
if($_POST['age']>18 && $_POST['age']<35)
$age2 = 'young ';
if($_POST['age']>40 && $_POST['age']<50)
$age2 = 'middle age ';
if($_POST['age']>60)
$age2 = 'old men ';
$array[] = array('age'=>$age2,'allergies'=>$allergies,'vege'=>$vege,'bmi'=>$bmi2,'solution'=>$solution);
i++
}
Then, i want to compare each element in that array with input i entered and calculate sum for each row of array :
foreach($array as $cases) {
if($cases['allergies'] == $_POST['allergies']){
$count = 1;
}
if($cases['vege'] == $_POST['vege']){
$count1 = 1;
}
if($cases['bmi'] == $bmi2)
$count2 = 1;
if($cases['age'] == $age2)
$count3 = 1;
$sum = $count + $count1 + $count2 + $count3;
echo $sum;
}
Lets say i have entered age,bmi, allergies and vege which is all are the same like first row of database, the the total sum that should be output is 4 because 4 same comparison of data. In this case that i try, every row of database should have different total sum because its not all the same.But i did not get the output that i want, this is the example of the wrong output:
0
4
4
4
4
4
4
4
4
(assuming i have 8 rows of database in my phpmyadmin)
The first row of database after compared manually the sum is 4 but it seems like when it continue looping the next row take the same amount as prev row.
When you do this loop:
foreach($array as $cases) {
if($cases['allergies'] == $_POST['allergies']){
$count = 1;
}
if($cases['vege'] == $_POST['vege']){
$count1 = 1;
}
if($cases['bmi'] == $bmi2)
$count2 = 1;
if($cases['age'] == $age2)
$count3 = 1;
$sum = $count + $count1 + $count2 + $count3;
echo $sum;
}
You are not resetting the $count, $count1, etc. variables between iterations. That is why
when it continue looping the next row take the same amount as prev
row.
I would say you probably don't even need these separate variables unless you are using them for something else that isn't included in the question. You can just initialize sum to zero for each repetition, then increment it directly if the conditions match.
foreach($array as $cases) {
$sum = 0;
if($cases['allergies'] == $_POST['allergies']){
$sum++;
}
if($cases['vege'] == $_POST['vege']){
$sum++;
}
if($cases['bmi'] == $bmi2) {
$sum++;
}
if($cases['age'] == $age2) {
$sum++;
}
echo $sum;
}
Incidentally, it looks like the way you are setting bmi and age in the first loop will make those values always match. I'm not sure if that's what you intended, but it seems kind of unlikely.
This is wrong:
foreach($array as $array)
You take the multi-dimensional array, which goes by the name $array, and iterate over each item in it, which is also assigned to $array. This is asking for weird behavior. Use a different variable. Array variables don't have to be named $array.
// Start variable sum
$sum = 0:
// For each $_POST[] in array
foreach($_POST as $key => $value){
// If Key in $_POST exists add sum
if(array_key_exists($key,$array)){
++$sum;
}
}
echo $sum;

More elegant way of looping through array and aggregating result in PHP

I need to loop through a set of data (example below) and generate an aggregate. Original data format is CSV (but could be other kind).
LOGON;QUERY;COUNT
L1;Q1;1
L1;Q1;2
L1;Q2;3
L2;Q2;1
I need to group the quantities by LOGON and QUERY, so at the end I would have an array like:
"L1-Q1" => 3,
"L1-Q2" => 3,
"L2-Q1" => 1,
I usually use a code like this:
$logon = NULL;
$query = NULL;
$count = 0;
$result = array();
// just imagine I get each line as a named array
foreach ($csvline as $line) {
if ($logon != $line['logon'] || $query != $line['query']) {
if ($logon !== NULL) {
$result[$logon . $query] = $count;
}
$logon = $line['logon'];
$query = $line['query'];
$count = 0;
}
$count += $line['count'];
}
$result[$logon . $query] = $count;
Sincerely, I don't think this is nice, as I have to repeat last statement to include last line. So, is there a more elegant way of solving this in PHP?
Thanks!
You simply would need to check for the existence of a key, then increment - create missing keys at any time with value 0.
Then you dont need to repeat anything at any time:
$result = array();
foreach ($csvline as $line) {
if (!isset($result[$line['logon'] . $line['query']])){
//create entry
$result[$line['logon'] . $line['query']] = 0;
}
//increment, no matter what we encounter
$result[$line['logon'] . $line['query']] += $line['count'];
}
For readability and to avoid misstakes, you should generate the key just one time, instead of performing the same concatenation over and over:
foreach ($csvline as $line) {
$curKey = $line['logon'] . $line['query'];
if (!isset($result[$curKey])){
//create entry
$result[$curKey] = 0;
}
//increment, no matter what we encounter
$result[$curKey] += $line['count'];
}
this would allow you to refactor the key without touching several lines of code.

Display two arrays in the same table

$row = $query->fetchAll(PDO::FETCH_ASSOC);
$num_rows = count($row);
for ($i = 0; $i < $num_rows; $i++)
{
$title = htmlspecialchars($row[$i]['title']);
$author =htmlspecialchars($row[$i]['author']);
$school =htmlspecialchars($row[$i]['school']);
$solution = $row[$i]['solution'];
$notes = $row[$i]['notes'];
$ad = array($title, $price, $author, $school, $contact, $content, $date);
$inlcude = array($solutions, $notes);
$field = 0;
echo "<table border='1'>";
// foreach($inlcude as $in) This failled miserably
foreach ($ad as $post)
{
if ($field < 3) //The first three values are placed in the first row
{
echo "<td>$post</td>";
}
if ($field >= 3)
{
echo "<tr><td>$post</td><td>$in</td></tr>";
}
$field++;
}
echo '</table>';
}
I have two arrays and I would like to display them in different columns in my table. $ad displays perfectly fine but I'm having trouble displaying the contents in $inlcude in the second column. I've tried putting another foreach loop to iterate through contents of the second array but that really screws up my table by placing random values in different places on the table. Besides the foreach loop, I don't know of any other way to iterate through the array. Any suggestions would be appreciated.Thanks!
I want the graph to look like this where $p=$post and $i=$in. Moreover, three columns in first row and two columns in every row after that
$p $p $p
$p $i
$p $i
Assuming that your arrays are formatted correctly, you probably want to use array_shift(). Try something like this:
// Start by copying the $include array, because array_shift() is a destructive
// operation and you might want to use $includes again.
$includes_copy = $include;
// Start with your leading <tr> cell.
echo "<tr>";
// Now loop your ad array.
foreach ($ad as $post) {
//The first three values are placed in the first row.
if ($field < 3) {
echo "<td>$post</td>";
$field++;
}
if ($field == 3) {
echo "</tr>"; // Closing tags are good form.
}
if ($field >= 3) {
// Using array_shift() will return the first element from the array.
// The returned element will be removed from the array.
$in = array_shift($includes_copy);
// $post is populated from foreach(), $in is populated by array_shift().
echo "<tr><td>$post</td><td>$in</td><td></td></tr>";
$field += 3;
}
}
Basically, the concept is that foreach($array as $val) is logically equivalent to while($val = array_shift($array)), meaning that you can run two foreach() at the same time. The only difference is that array_shift() is destructive.

php arrays and mysql query

This is driving me nuts! I need to fill up and HTML table with values that I pulled out from a DB.
The HTML table has 100 one td for each value.
I have an array that I populate doing this:
$x = 1;
$ArrayA = array();
for ($x = 1; $x <= 100; $x++) {
$ArrayA[$x] = 0;
}
So now I have an array with 100 values, right?
Then I query my DB, and get the result that I "want"
(select num from table1)
6 rows with the following values:
1,3,14,50,100.
Then I insert the values from my query into the $ArrayA that I populated before with one hundred 0's
$x = 1;
while ($row = mysql_fetch_array($result))
{
extract($row);
$ArrayA[$x] = "$num";
$x++;
}
Now $ArrayA has this:
1,3,14,17,100,0,0,0,0,0,0,0,0,0,0,0,0.....
And my goal is to replace with a 0 where I should have a "next" number, hard to explain..
I need this result:
1,0,3,0,0,0,0,0,0,0,0,0,0,14,0,0,17,0....
I tried to use PHP array_splice, but it did not work.
I tried with some if statements but my logic and programing experience is not that good.
Any suggestions?
Thanks
If i understand this right, you want to add a zero after every element returned by your query? Right? If so, why not add a zero right after you add an element into the array?
$x = 1; while ($row = mysql_fetch_array($result)) {
extract($row);
$ArrayA[$x] = "$num";
$x++;
$ArrayA[$x] = "0"; //adds zero after every $num insert
}
Maybe you can clarify if this isn't what you're asking...
$match_rows = mysql_fetch_array($result);
$rows = range(1,100);
foreach( $rows as $row){
echo '<td>';
if( in_array($row, $match_rows) ){
echo $row;
}else{
echo 0;
}
echo '</td>' . PHP_EOL;
}
Sorry, that is untested - it could be shorter or neater, but like that possibly illustrates another way of achieving what you want.
I think this is what you want for your second code block:
while ($row = mysql_fetch_array($result))
{
extract($row);
if($num > 0 && $ <= 100 )
{
$ArrayA[$num] = "$num";
}
}
If your DB values are 3, 10, 15, 22, 100, you'd end up with 0,0,3,0,0,0,0,0,0,10,0,0,0,0,15, etc etc.

Categories