I need to write a script that returns the next-to-last element in a foreach loop. Something like the below concept. How would I go about doing so?
foreach($row as $r) {
if (element index is last - 1) {
echo "The next-to-last element is" . $r;
}
}
This should work for you:
Just get the keys of your array into a variable and then check if the current key of the iteration is equal to the penultimate key.
$keys = array_keys($row);
$penultimatekey = count($row)-2 >= 0 ? count($row)-2 : 0;
foreach($row as $k => $r) {
if ($k == $keys[$penultimatekey]) {
echo "The next-to-last element is" . $r;
}
}
Move the pointer to the end, then rewind it by one spot. No extra loops or counting the array.
end($row);
prev($row);
echo "The next-to-last element is: " . current($row);
Related
I'm trying to figure out how to make an array add the value of the previous array, so far, looking at the PHP manual I got how to add a single value for each position of the array, but I don't understand how can I add the previous value to the actual value.
That's what i got checking the manual:
<!DOCTYPE html>
<head>
</head>
<body>
<?php
foreach (array(422, 322, -52323, 7452) as &$val) {
$val = $val + 2;
echo "$val<br>";
}
?>
</body>
I know that I have to change the "+ 2" with "add previous value" but don't know how I can tell it to do that, tried to add "$val[0]" or "$val[$i]" but not doing what I think it does.
Thank you!
You've complicated matters by putting the array directly into foreach. To get the previous value, you need to have access to the array itself.
Once you have that, you can get the index of the current value with foreach, which you can use to determine the index of the previous value:
$array = array(422, 322, -52323, 7452);
foreach ($array as $index => &$val) {
// the first index is 0, in that case there is no previous value
// (trying to access $array[$index - 1] ($array[-1]) will fail then)
if ($index > 0) {
$val = $val + $array[$index - 1];
}
echo "$val<br>";
}
You are directly iterating over an array, and in that case you don't need the reference to &$val, you can just use $val
If you don't want to store the array in a variable, you could also "remember" the previous value of the iteration (which will also work in case the keys are not numerical for example)
$previous = null;
foreach (array(422, 322, -52323, 7452) as $val) {
if ($previous) {
$previous += $val;
} else {
$previous = $val;
}
echo $previous . PHP_EOL;
}
Output
422
744
-51579
-44127
See a Php demo.
I try count elements inside loop, with the same value, as i put in my title, now i show my little script fot try to do this :
<?php
$values="1,2,3~4,5,2~7,2,9";
$expt=explode("~",$values);
foreach ($expt as $expts)
{
$expunit=explode(",",$expts);
$bb="no";
foreach($expunit as $expunits)
{
//// $expunit[1] it´s the second value in each explode
if ($expunits==="".$expunit[1]."")
{
$bb="yes";
}
if ($bb=="yes")
{
print "$expunits --- $expunit[1] ok, value it´s the same<br>";
}
else
{
print " $expunits bad, value it´s not the same<br>";
}
}
}
?>
THE SCRIPT MUST SHOW DATA IN THIS WAY :
$values="1,2,3~4,5,2~7,2,9";
**FIRST ELEMENTS WITH THE SAME SECOND ELEMENT, IN VALUES COMMON VALUE IT´S NUMBER 2, BECAUSE IT´S IN SECOND POSITION **
FIRST :
1,2,3
7,2,9
LAST THE OTHERS
4,5,2
I try verificate the second position, between delimeters, because it´s value i want verificate for count inside loop, while explode string, actually give bad values, i think it´s bad because don´t get real or right values, i don´t know if it´s possible do it or with other script or change something in this
Thank´s Regards
EDIT - this is a bit closer to what you are looking for (sorry it is not perfect as I do not have time to work on it fully):
$values="1,2,3~4,5,2~7,2,9";
$values=explode("~",$values);
foreach($values as $key => $expt) {
$expit=explode(",",$expt);
$search_value = $expit[1];
$matched=array();
foreach($values as $key2 => $expt2) {
if($key !== $key2) {
$expit2=explode(",",$expt2);
if($expit[1]==$expit2[1]) {
$matched[] = $expit[1];
}
}
}
}
array_unique($matched);
foreach($matched as $match) {
$counter = 0;
$no_matches = array();
echo "<br />Matching on digit ".$match;
foreach($values as $key3 => $expt3) {
$expit3=explode(",",$expt3);
if($match == $expit3[1]) {
echo "<br />".$expt3;
$counter++;
} else {
$no_matches[] = $expt3;
}
}
echo "<br />Total number of matches - ".$counter;
echo "<br />Not matching on digit ".$match;
foreach($no_matches as $no_match) {
echo "<br />".$no_match;
}
}
Outputs:
Matching on digit 2
1,2,3
7,2,9
Total number of matches - 2
Not matching on digit 2
4,5,2
I was wondering if PHP has a gracefull method to find the first, last and/or nth row in a foreach loop.
I could do it using a counter as follows:
$i = 0;
$last = count($array)-1;
foreach ($array as $key => $row) {
if ($i == 0) {
// First row
}
if ($i == $last) {
// Last row
}
$i++;
}
But somehow this feels like a bit of a dirty fix. Any solutions or suggestions?
Edit
As suggested in the comments I moved the count($array) outside the loop.
foreach ($array as $key => $row) {
$index = array_search($key, array_keys($array));
if ($index == 0) {
// First row
}
if ($index == count($array) - 1) {
// Last row
}
}
In php we have current and end function to get first and last value of array.
<?php
$transport = array('foot', 'bike', 'car', 'plane');
echo $first = current($transport); // 'foot';
echo $end = end($transport); // 'plane';
?>
Modified :
Easy way without using current or end or foreach loop:
$last = count($transport) - 1;
echo "First : $transport[0]";
echo "</br>";
echo "Last : $transport[$last]";
Using Arrays
For the first element in an array you can simply seek $array[0];. Depending on the array cursor you can also use current($array);
For the middle of an array you can use a combination of array_search() and array_keys().
For the end of an array you can use end($array); noting that this aslso moves the array cursor to the last element as well (as opposed to simply returning the value).
Using Iterators
However ArrayIterator's may also work well in your case:
The first element is available at ArrayIterator::current(); once constructed. (If you're halfway through the iterator you'll need to reset().)
For the n'th or a middle element you can use an undocumented Iterator::seek($index); method.
For the last element you can use a combination of seek() and count().
For example:
$array = array('frank' => 'one',
'susan' => 'two',
'ahmed' => 'three');
$arrayobject = new ArrayObject($array);
$iterator = $arrayobject->getIterator();
// First:
echo $iterator->current() . PHP_EOL;
// n'th: (taken from the documentation)
if($iterator->valid()){
$iterator->seek(1); // expected: two, output: two
echo $iterator->current() . PHP_EOL; // two
}
// last:
$iterator->seek(count($iterator)-1);
echo $iterator->current() . PHP_EOL;
$arr = ["A", "B", "C", "D", "E"];
reset($arr);
// Get First Value From Array
echo current($arr);
// Get Last Value From Array
echo end($arr);
Visit below link for details of above used functions.
reset() : http://php.net/manual/en/function.reset.php
current() : http://php.net/manual/en/function.current.php
end() : http://php.net/manual/en/function.end.php
I have an array that looks like this:
$elm = 'a,b,c';
I need the values of the array so I use explode to get to them:
$q = explode(",",$elm);
I then would like to echo every single item into a span, so I make an array:
$arr = array();
foreach($html->find($q[0]) as $a) {
$arr[] = $a->outertext;
}
$arr2 = array();
foreach($html->find($q[1]) as $b) {
$arr2[] = $b->outertext;
}
$arr3 = array();
foreach($html->find($q[2]) as $c) {
$arr3[] = $c->outertext;
}
And then finally I output like this:
echo "<ul>";
for($i=0; $i<sizeof($arr + $arr2 + $arr3); $i++)
{
echo "<li>";
echo "<span>".$arr[$i]."</span>";
echo "<span>".$arr2[$i]."</span>";
echo "<span>".$arr3[$i]."</span>";
echo "</li>";
}
echo "</ul>";
The problem is that I have to write all the items ($q[0] + $q[1] + $q[2]) and the corresponding span (<span>".$arr[$i]."</span>) This is a problem because in reality I don't know what and how long the first array ($elm) is. Therefore I don't want to 'physically' write down all the span elements but rather create them on the fly depending on the array $elm. I tried many things but I can't figure it out.
The basic issue here is that you don't know how many elements $elm will contain. foreach is the best choice here, as it doesn't require the length of the array to loop through it.
Use a nested foreach loop to store all the outertexts in an array:
foreach (explode(",", $elm) as $elem) {
foreach ($html->find($elem) as $a) {
$arr[$elem][] = $a->outertext;
}
}
$arr[$elem][] is the important bit here. On each iteration of the outer loop, the value of $elem will be a, b and c. On each iteration of the inner loop, it will create a new index in the array: $arr['a'], $arr['b'] and $arr['c'] and add the outertext values to the respective index.
Once you've stored all the required values in the array, it's only a matter of looping through it. Since we have a multi-dimensional array here, you will need to use a nested loop again:
echo "<ul>";
foreach ($arr as $sub) {
echo "<li>";
foreach ($sub as $span) {
echo "<span>".$span."</span>";
}
echo "</li>";
}
echo "</ul>";
Is it possible to find the foreach index?
in a for loop as follows:
for ($i = 0; $i < 10; ++$i) {
echo $i . ' ';
}
$i will give you the index.
Do I have to use the for loop or is there some way to get the index in the foreach loop?
foreach($array as $key=>$value) {
// do stuff
}
$key is the index of each $array element
You can put a hack in your foreach, such as a field incremented on each run-through, which is exactly what the for loop gives you in a numerically-indexed array. Such a field would be a pseudo-index that needs manual management (increments, etc).
A foreach will give you your index in the form of your $key value, so such a hack shouldn't be necessary.
e.g., in a foreach
$index = 0;
foreach($data as $key=>$val) {
// Use $key as an index, or...
// ... manage the index this way..
echo "Index is $index\n";
$index++;
}
It should be noted that you can call key() on any array to find the current key its on. As you can guess current() will return the current value and next() will move the array's pointer to the next element.
Owen has a good answer. If you want just the key, and you are working with an array this might also be useful.
foreach(array_keys($array) as $key) {
// do stuff
}
You can create $i outside the loop and do $i++ at the bottom of the loop.
These two loops are equivalent (bar the safety railings of course):
for ($i=0; $i<count($things); $i++) { ... }
foreach ($things as $i=>$thing) { ... }
eg
for ($i=0; $i<count($things); $i++) {
echo "Thing ".$i." is ".$things[$i];
}
foreach ($things as $i=>$thing) {
echo "Thing ".$i." is ".$thing;
}
I think best option is like same:
foreach ($lists as $key=>$value) {
echo $key+1;
}
it is easy and normally
PHP arrays have internal pointers, so try this:
foreach($array as $key => $value){
$index = current($array);
}
Works okay for me (only very preliminarily tested though).
I use ++$key instead of $key++ to start from 1. Normally it starts from 0.
#foreach ($quiz->questions as $key => $question)
<h2> Question: {{++$key}}</h2>
<p>{{$question->question}}</p>
#endforeach
Output:
Question: 1
......
Question:2
.....
.
.
.
Jonathan is correct. PHP arrays act as a map table mapping keys to values. in some cases you can get an index if your array is defined, such as
$var = array(2,5);
for ($i = 0; $i < count($var); $i++) {
echo $var[$i]."\n";
}
your output will be
2
5
in which case each element in the array has a knowable index, but if you then do something like the following
$var = array_push($var,10);
for ($i = 0; $i < count($var); $i++) {
echo $var[$i]."\n";
}
you get no output. This happens because arrays in PHP are not linear structures like they are in most languages. They are more like hash tables that may or may not have keys for all stored values. Hence foreach doesn't use indexes to crawl over them because they only have an index if the array is defined. If you need to have an index, make sure your arrays are fully defined before crawling over them, and use a for loop.
I solved this way, when I had to use the foreach index and value in the same context:
$array = array('a', 'b', 'c');
foreach ($array as $letter=>$index) {
echo $letter; //Here $letter content is the actual index
echo $array[$letter]; // echoes the array value
}//foreach
I normally do this when working with associative arrays:
foreach ($assoc_array as $key => $value) {
//do something
}
This will work fine with non-associative arrays too. $key will be the index value. If you prefer, you can do this too:
foreach ($array as $indx => $value) {
//do something
}
foreach(array_keys($array) as $key) {
// do stuff
}
I would like to add this, I used this in laravel to just index my table:
With $loop->index
I also preincrement it with ++$loop to start at 1
My Code:
#foreach($resultsPerCountry->first()->studies as $result)
<tr>
<td>{{ ++$loop->index}}</td>
</tr>
#endforeach