Add previous value on array - PHP - php

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.

Related

How does this function return the first dupe from an array?

I have a task (or more like a challenge) found on Code-Signal (a site where do you can do some programming-related tasks. This special task was asked by google in an interview:
If you want to try it for yourself: Code-Fight.
After solving an issue, you are allowed to see other solutions.
My task was "find the first dupe in an array". I managed to do this (i'll show the way), but I'm not happy with my result. After investigating the top-solutions, I was confused, since I don't understand whats going on there.
This was (a) given example input array
$a = [2, 1, 3, 5, 3, 2]
My solution:
function firstDuplicate($a) {
$onlyDupesArray= array();
$countedValues = array_count_values($a);
// remove all entries which are only once in the array
foreach($a as $k => $v) {
if($countedValues[$v] > 1) {
$onlyDupesArray[$v] = $v;
}
}
// get rid of dupes
$uniqueDupesArray = array_unique($onlyDupesArray);
$firstEncounter = PHP_INT_MAX;
foreach($uniqueDupesArray as $k => $v) {
if(array_keys($a, $v)[1] < $firstEncounter) {
$firstEncounter = array_keys($a, $v)[1];
}
}
if(is_null($a[$firstEncounter])) {
return -1;
} else {
return $a[$firstEncounter];
}
}
It works in every test-case and I solved the challenge. However, the top-solution was this:
function firstDuplicate($a) {
foreach ($a as $v)
if ($$v++) return $v;
return -1;
}
I know what a variable variable is, but haven't seen this in the wild-life yet until now.
What does the references variable do here? How is this returning a dupe? Does it somehow compare if there is already a value for a key with this typing? Does $$v++ reference a key in an array?
Needlessly to say, I like this approach muche more. It seems way more efficient and better to maintain.
Is this "common practice"?
It is creating numbered variables. $2, $1, $3 etc.
$v in the foreach contains the current number, 2. By doing $test = 2; echo $$test we can see what is in $2 right now. It is normally empty. Now, by doing $$v++, it will return the current value (empty, or actually, variable does not exist), but ++ will put '1' in it. The whole statement itself will return 0, since ++ is not in front of the variable.
Consider this code:
$arr = [2, 1, 3, 5, 3, 2];
foreach($arr as $v)
{
$$v++;
}
$test = 3;
echo $$test;
It will show that the value of $3 equals 2, because we did 2 times ++ on $3.
The only reason this is weird is that normally you can't use variables starting with numbers. Maybe this makes it clearer?:
$arr = [2, 1, 3, 5, 3, 2];
foreach($arr as $v)
{
$v='a'.$v;
$$v++;
}
echo "a3 = $a3\n"; // 2
echo "a2 = $a2\n"; // 2
echo "a1 = $a1\n"; // 1
echo "a5 = $a5\n"; // 1
To answer the question "Is this "common practice"?". No, I would personally not use variable variables, as this can in some cases been considered as a security problem. I personally like the following solution better, which is the same, but uses an array, and does not throw notices:
function firstDuplicate($a) {
$arr = [];
foreach ($a as $v)
if (in_array($v, $arr))
return $v;
else
$arr[] = $v;
return -1;
}
The variable variables solution is a creative one, though!
By specifying your variable with an additional $ (variables variable) PHP creates a "hidden/fake array".
While running each index gets filled with a "0":
After the first run you got something like
$array[2] = 0;
After the next run the index 1 gets filled:
$array[1] = 0;
$array[2] = 0;
Since a "0" is treated as false, your condition becomes valid after the first duplicate (3):
$array[1] = 0;
$array[2] = 0;
$array[3] = 1; // <-- TRUE
$array[5] = 0;

Finding the first, last and nth row in a foreach loop

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

Find Next to Last Element in PHP Foreach

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);

PHP Find last key of associative multidimensional array

This is what I have tried:
foreach ($multiarr as $arr) {
foreach ($arr as $key=>$val) {
if (next($arr) === false) {
//work on last key
} else {
//work
}
}
}
After taking another look, I thinknext is being used wrong here, but I am not sure what to do about it.
Is it possible to see if I'm on the last iteration of this array?
$lastkey = array_pop(array_keys($arr));
$lastvalue = $arr[$lastkey];
If you want to use it in a loop, just compare $lastkey to $key
You will need to keep a count of iterations and check it against the length of the array you are iterating over. The default Iterator implementation in PHP does not allow you to check whether the next element is valid -- next has a void return and the api only exposes a method to check whether the current position is valid. See here http://php.net/manual/en/class.iterator.php. To implement the functionality you are thinking about you would have to implement your own iterator with a peek() or nextIsValid() method.
Try this:
foreach ($multiarr as $arr) {
$cnt=count($arr);
foreach ($arr as $key=>$val) {
if (!--$cnt) {
//work on last key
} else {
//work
}
}
}
See below url i think it help full to you:-
How to get last key in an array?
How to get last key in an array?
Update:
<?php
$array = array(
array(
'first' => 123,
'second' => 456,
'last' => 789),
array(
'first' => 123,
'second' => 456,
'last_one' => 789),
);
foreach ($array as $arr) {
end($arr); // move the internal pointer to the end of the array
$key = key($arr); // fetches the key of the element pointed to by the internal pointer
var_dump($key);
}
output:
string(4) "last" string(4) "last_one"
This function (in theory, I haven't tested it) will return the last and deepest key in a multidemnsional associative array. Give I a run, I think you'll like it.
function recursiveEndOfArrayFinder($multiarr){
$listofkeys = array_keys($multiarr);
$lastkey = end($listofkeys);
if(is_array($multiarr[$lastkey])){
recursiveEndOfArrayFinder($multiarr[$lastkey]);
}else{
return $lastkey;
}
}

How to find the foreach index?

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

Categories