I have a foreach loop. There has uncountable value. I want to print last 3 values.
foreach($arr as $key=>$value) {
//print last 3 value.
}
Try this:
$i = 0;
foreach($arr as $key=>$value) {
if (count($arr) - $i < 4)
print($value);
$i++;
}
Try this you can use like this
$i = 0;
$len = count($array);
foreach ($array as $item) {
if ($i == 0) {
// first
} else if ($i == $len - 3) {
// last
}
else if ($i == $len - 2) {
// last
}
else if ($i == $len - 1) {
// last
}
// …
$i++;
}
Related
I want to get the first element and ending element of the nested foreach loop the condition is working fine for first loop but it's not working for the second nested loop.
PHP code
$i = 0;
$len = count($category_tbl_data);
foreach($category_tbl_data as $row) {?>
if ($i == 0) {
// first element working fine
}
if ($i == $len - 1)
{
// last element working fine
}
$j=0;
$len2 = count($services);
foreach($services as $s){
if($row['category']['cat_id'] == $s['Service']['category_id'])
{
if ($j == 0) {
// first element working fine
}
if ($j == $len2 - 1)
{
// last element not working
}
}
$j++;
}
}
Image Here
Answered
Could there be a chance that the last element is not full-filling if($row['category']['cat_id'] == $s['Service']['category_id']) ?
Try placing if ($j == 0) {} and if ($j == $len2 - 1){} outside if($row['category']['cat_id'] == $s['Service']['category_id']){} if you want to operate on the exact first and last element of $services, regardless what $s is.
<?php
$len = count($category_tbl_data);
foreach($category_tbl_data as $i => $row) {
if ($i == 0)
{
// first element working fine
}
if ($i == $len - 1)
{
// last element working fine
}
$len2 = count($services);
foreach($services as $j => $s){
if ($j == 0)
{
// first element
}
if($row['category']['cat_id'] == $s['Service']['category_id'])
{
}
if ($j == $len2 - 1)
{
// last element
}
$j++;
}
}
?>
If you want to operate on the first and last element of $services which satisfies $row['category']['cat_id'] == $s['Service']['category_id'], you should pass the array once beforehand to find out the exact indices of them first.
<?php
$len = count($category_tbl_data);
foreach($category_tbl_data as $i => $row) {
if ($i == 0)
{
// first element working fine
}
if ($i == $len - 1)
{
// last element working fine
}
$len2 = count($services);
$first = -1;
$last = -1;
foreach($services as $j => $s)
{
if($row['category']['cat_id'] == $s['Service']['category_id'])
{
if($first < 0)
{
$first = $j;
}
$last = $j;
}
}
foreach($services as $j => $s){
if($row['category']['cat_id'] == $s['Service']['category_id'])
{
if ($j == $first)
{
// first element
}
if ($j == $last)
{
// last element
}
}
}
}
?>
Im trying to solve one challenge where you have to check all string substrings are they anagrams. The condition is basically For S=abba, anagramic pairs are: {S[1,1],S[4,4]}, {S[1,2],S[3,4]}, {S[2,2],S[3,3]} and {S[1,3],S[2,4]}
Problem is that I have string with 100 chars and execution time should be below 9 secs. My time is around 50 secs... Below is my code, I will appreciate any advice - if you give me only directions or pseudo code it is even better.
$time1 = microtime(true);
$string = 'abdcasdabvdvafsgfdsvafdsafewsrgsdcasfsdfgxccafdsgccafsdgsdcascdsfsdfsdgfadasdgsdfawdascsdsasdasgsdfs';
$arr = [];
$len = strlen($string);
for ($i = 0; $i < strlen($string); $i++) {
if ($i === 0) {
for ($j = 1; $j <= $len - 1; $j++) {
$push = substr($string, $i, $j);
array_push($arr, $push);
}
} else {
for ($j = 1; $j <= $len - $i; $j++) {
$push = substr($string, $i, $j);
array_push($arr, $push);
}
}
}
$br = 0;
$arrLength = count($arr);
foreach ($arr as $key => $val) {
if ($key === count($arr) - 1) {
break;
}
for ($k = $key + 1; $k < $arrLength; $k++) {
if (is_anagram($val, $arr[$k]) === true) {
$br++;
}
}
}
echo $br."</br>";
function is_anagram($a, $b)
{
$result = (count_chars($a, 1) == count_chars($b, 1));
return $result;
}
$time2 = microtime(true);
echo "Script execution time: ".($time2-$time1);
Edit:
Hi again, today I had some time so I tried to optimize but couldnt crack this... This is my new code but I think it got worse. Any advanced suggestions ?
<?php
$string = 'abdcasdabvdvafsgfdsvafdsafewsrgsdcasfsdfgxccafdsgccafsdgsdcascdsfsdfsdgfadasdgsdfawdascsdsasdasgsdfs';
$arr = [];
$len = strlen($string);
for ($i = 0; $i < strlen($string); $i++) {
if ($i === 0) {
for ($j = 1; $j <= $len - 1; $j++) {
$push = substr($string, $i, $j);
array_push($arr, $push);
}
} else {
for ($j = 1; $j <= $len - $i; $j++) {
$push = substr($string, $i, $j);
array_push($arr, $push);
}
}
}
$br = 0;
$arrlen = count ($arr);
foreach ($arr as $key => $val) {
if (($key === $arrlen - 1)) {
break;
}
for ($k = $key + 1; $k < $arrlen; $k++) {
$result = stringsCompare($val,$arr[$k]);
if ($result === true)
{
$br++;
}
}
echo $br."\n";
}
function stringsCompare($a,$b)
{
$lenOne = strlen($a);
$lenTwo = strlen ($b);
if ($lenOne !== $lenTwo)
{
return false;
}
else {
$fail = 0;
if ($lenOne === 1) {
if ($a === $b) {
return true;
}
else
{
return false;
}
}
else
{
for ($x = 0; $x < $lenOne; $x++)
{
$position = strpos($b,$a[$x]);
if($position === false)
{
$fail = 1;
break;
}
else
{
$b[$position] = 0;
$fail = 0;
}
}
if ($fail === 1)
{
return false;
}
else
{
return true;
}
}
}
}
?>
You should think of another rule that all anagrams of a certain string can meet. For example, something about the number of occurrences of each character.
Why does this not make two arrays one within 7 numbers and one within 2 numbers in it?
It somehow combines the both into one.
When i echo $arvottuLottoRivi and $lottoLisaNumerot in my HTML page the result is:
$arvottuLottoRivi (1,2,3,4,5,6,7,8,9,10) : $lottoLisaNumerot
all the seven numbers.
I have now tried three different styles but same thing happens in all cases
// VARAIBLES
$lottoNumerot = $_POST["lottoNumerot"];
$mahdollisetNumerot = array("1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20","21","22","23","24","25","26","27","28","29","30","31","32","33","34","35","36","37","38","39");
$i = 0;
$l = 0;
$k = 0;
//ARRAYS
$arvottuLottoRivi = array();
$lottoLisaNumerot = array();
$tenNumbersArray = array();
//FUNCTIONS
$numeroidenRandomointi = array_rand($mahdollisetNumerot, 10);
// COUNTS ARRAY LENGHT
$lottoRivinPituus = count($numeroidenRandomointi);;
// LOOPS
foreach($numeroidenRandomointi as $randomNumero){
while($i <= $lottoRivinPituus){
$i++;
}
$randomToArray = array_push($tenNumbersArray, $randomNumero);
}
// LOOPIT
foreach($tenNumbersArray as $randomToSite){
while($l <= $lottoRivinPituus){
$l++;
}
if($l <= 7){
array_push($arvottuLottoRivi, $randomToSite);
}
}
foreach($tenNumbersArray as $randomToSiteLisanuimerot){
while($k <= $lottoRivinPituus){
$k++;
}
if($k >= 7){
array_push($lottoLisaNumerot, $randomToSiteLisanuimerot);
}
}
$arvottuLottoRivi = implode(' ', $arvottuLottoRivi);
$lottoLisaNumerot = implode(' ', $lottoLisaNumerot);
When you write:
foreach($tenNumbersArray as $randomToSiteLisanuimerot){
while($k <= $lottoRivinPituus){
$k++;
}
if($k >= 7){
array_push($lottoLisaNumerot, $randomToSiteLisanuimerot);
}
}
the while loop is equivalent to:
$k = $lottoRivinPituus + 1;
Since $lottoRivinPituus is 10, $k is always 11. Therefore, if($k >= 7) is always true, so all elements of $randomToSiteLisanuumerot are copied to $lottoLisaNumerot. Similarly, in the previous loop, the test if ($l <= 7) is always false, so nothing is copied to $arvottuLottoRivi.
I think you were trying to test the current position in the loop, not the count of all elements in the array. You can do it like this:
foreach($tenNumbersArray as $l => $randomToSite){
if($l < 7){
array_push($arvottuLottoRivi, $randomToSite);
}
}
foreach($tenNumbersArray as $k => $randomToSiteLisanuimerot){
if($k >= 7){
array_push($lottoLisaNumerot, $randomToSiteLisanuimerot);
}
}
But this wastes time iterating over elements it doesn't care about. A better way would be:
$arvotSize = min(7, $lottoRivinPituus);
for ($l = 0; $l < $arvotSize; $l++) {
array_push($arvottuLottoRivi, $tenNumbersArray[$l]);
}
for ($k = $arvotSize; $k < $lottoRivinPituus; $k++) {
array_push($lottoLisaNumerot, $tenNumbersArray[$k]);
}
I really didn't get your code.
Why don't use rand function?
$randomNumbers1 = array();
$randomNumbers2 = array();
$i = 0;
while ($i < 7) {
$aNumber = rand(1, 39);
if (!in_array($aNumber, $randomNumbers1)) {
$randomNumbers1[] = $aNumber;
$i++;
}
}
$i = 0;
while ($i < 2) {
$aNumber = rand(1, 39);
if (!in_array($aNumber, $randomNumbers2)) {
$randomNumbers2[] = $aNumber;
$i++;
}
}
And if the seconds array cannot contains any number within the first one:
$i = 0;
while ($i < 2) {
$aNumber = rand(1, 39);
if (!in_array($aNumber, $randomNumbers2) && !in_array($aNumber, $randomNumbers1)) {
$randomNumbers2[] = $aNumber;
$i++;
}
}
I have the following code:
$chart_data = array();
foreach ($range as $range_day) {
foreach ($numbers as $number) {
if($range_day == $number['date']){
#$chart_data[$range_day] += $number['events'];
} else {
if(isset($chart_data[$range_day])){
$chart_data[$range_day] += 0;
}
}
}
}
This line: $chart_data[$range_day] += 0; was giving me an undefined index error, so I added the isset check, but it's not set so it wrecks my array. I know that it's not set, and I don't care, but I read all over that the # solution is in poor taste. How can I remove the error the correct way?
You could just set it to zero at the beginning:
$chart_data = array();
foreach ($range as $range_day) {
$chart_data[$range_day] = 0;
foreach ($numbers as $number) {
if($range_day == $number['date']){
$chart_data[$range_day] += $number['events'];
} else {
if(isset($chart_data[$range_day])){
$chart_data[$range_day] += 0;
}
}
}
}
Did you take a look at the array_key_exists function: http://php.net/manual/en/function.array-key-exists.php ?
Something like:
$chart_data = array();
foreach ($range as $range_day) {
foreach ($numbers as $number) {
if(!array_key_exists($range_day, $array)) {
$chart_data[$range_day] = 0;
}
if($range_day == $number['date']){
$chart_data[$range_day] += $number['events'];
}
}
}
You can check if it's not set, then set it:
foreach ($numbers as $number) {
if (!isset($chart_data[$range_day])) {
$chart_data[$range_day] = 0;
}
if ($range_day == $number['date']) {
$chart_data[$range_day] += $number['events'];
} else {
$chart_data[$range_day] += 0; // you're just adding 0 so why have this line at all?
}
}
This answers assumes that there is the possibility that $range could contain a duplicate $range_day and so it won't overwrite the corresponding element in $chart_data.
Here's the issue:
I retrieve the following data string from my database:
$row->exceptions = '1,2,3';
After explode I need the below code to check each one of the exploded pieces
$exceptions = explode(",", $row->exceptions);
//result is
//[0] => 1
//[1] => 2
//[2] => 3
for ($i = 0; $i <= $row->frequency; $i++) {
if ($exceptions[] == $i) {
continue;
} else {
//do something else
}
}
How can I make $exceptions[] loop through all keys from the exploded array so it evaluates if ==$i?
Thanks for helping.
It should suffice to substitute:
if($exceptions[] == $i)
with:
if(in_array($i,$exceptions))
By the way, it eliminates the need for a nested loop.
Ah, should be straightforward, no?
$exceptions = explode(",", $row->exceptions);
for ($i = 0; $i <= $row->frequency; $i++) {
foreach($exceptions as $j){
if($j == $i){
// do something
break;
}
}
}
I think I understand what you are asking. Here's how you would test within that loop whether the key equals $i.
for ($i = 0; $i <= $row->frequency; $i++)
{
foreach ($exceptions as $key => $value)
{
if ($key == $i)
{
continue;
}
}
}