PHP make array start from key / position - php

I want to tell my array to start from key position 2 and then loop through the entire array, including the values before key position 2. I just want to use one array and specify the key position I start looping from. For example, here I am using array_splice, but it does not do what I want it to, could you help me please?
$names = array('Bill', 'Ben', 'Bert', 'Ernie');
foreach(array_slice($names, 2) as $name){
echo $name;
}
foreach(array_slice($names, 3) as $name){
echo $name;
}

If the keys are irrelevant, you can splice the array twice, and merge the resulting arrays, like this:
$names = array('Bill', 'Ben', 'Bert', 'Ernie');
$start = 2;
foreach( array_merge( array_slice($names, $start), array_slice( $names, 0, $start)) as $name){
echo $name;
}
You can see from the demo that this prints:
BertErnieBillBen
Alternatively, for efficiency, you can use two loops that are aware of wrapping around to the beginning, which will be more efficient since you are operating on the original array and not creating copies of it.
$start = 2;
for( $i = $start, $count = count( $names); $i < $count; $i++) {
echo $names[$i];
}
$i = 0;
while( $i < $start) {
echo $names[$i++];
}
You could also turn this into one single loop, and just encapsulate the logic for wrapping around inside the for.

$limit = 2; //so you can set your start index to an arbitrary number
$fn= function($a,$b) use ($limit){
if(($a < $limit && $b < $limit)
|| ($a >= $limit && $b >=$limit)) //$a and $b on the same side of $limit
return $a < $b ? -1 : ($a==$b ? 0 : 1);
if($a < $limit && $b > $limit) return 1; //because $a will always be considered greater
if($a >= $limit && $b < $limit) return -1; //because $b will always be considered greater
};
uksort($arr, $fn);
foreach($arr as $v) echo $v;

Related

How to get comma separated values and final value using a for loop?

PHP code:
$b = 1;
$ab = 100;
for ($b; $b < $ab; $b++)
{
$len = strlen($b);
$c = 0;
for ($c; $c < $len; $c++)
{
$split = str_split($b);
if ($split[$c] == 5)
{
echo $b . ',';
}
}
}
It's result is :
5,15,25,35,45,50,51,52,53,54,55,55,56,57,58,59,65,75,85,95,
But I want remove the final comma and get the last value.
Changes done.
1. Defined $result=array();;
2. Stored values in an array $result[]= $b;
3. Imploded an array with , $result= implode(",", $result);
PHP code demo
<?php
$b = 1;
$ab = 100;
$result=array();
for ($b; $b < $ab; $b++)
{
$len = strlen($b);
$c = 0;
for ($c; $c < $len; $c++)
{
$split = str_split($b);
if ($split[$c] == 5)
{
$result[]= $b;
}
}
}
$lastElement =end($result);//last element
$result= implode(",", $result);
print_r($result);
There is two way .Either you use all value in a array or explode the string into array
1st way is
$b = 1;
$ab = 100;
$arr=[];
for($b; $b < $ab; $b++){
$len = strlen($b);
$c = 0;
for($c; $c < $len; $c++){
$split = str_split($b);
if($split[$c] == 5){
$arr[]=$b;//push value into the array
}
}
}
echo implode(",",$arr);//create string from array
echo end($arr);// return the last value of a array
2nd way is
$b = 1;
$ab = 100;
$str="";
for($b; $b < $ab; $b++){
$len = strlen($b);
$c = 0;
for($c; $c < $len; $c++){
$split = str_split($b);
if($split[$c] == 5){
$str .=$b .','; //create a string with name str
}
}
}
$str=rtrim($str,','); //remove last comma of this string
echo $str;
$arr=explode(",",$str);//convert string to array
echo end($arr);//return the last value of this array
Every other answer is too inefficient because they are using str_split() in an inner for() loop to build the array.
Echoing your values and concatenating with a comma each time will require you to write a separate condition to handle the commas. This will just make your code messy. Best practice would be to store all of the values in an array, then use implode() to glue them together with commas -- this avoids the unwanted trailing comma. end() is the best way to extract the last value.
Here is a faster way (because it avoids unnecessary loops and function calls) to dynamically build your array, convert it to a csv string, and access the latest element in the array:
Code:
$d="5"; // must be declared as string for strpos()
$x11=$d*11; // set only duplicate occurrence in range
for($x=1; $x<100; ++$x){
if(strpos($x,$d)!==false){ // if at least one $d is found
$array[]=$x;
if($x==$x11){ // if two $d are found in integer
$array[]=$x;
}
}
}
echo implode(',',$array),"<br>Last number: ",end($array); // display
Output:
5,15,25,35,45,50,51,52,53,54,55,55,56,57,58,59,65,75,85,95
Last number: 95
This method makes 99 iterations, and 99 strpos() calls, and 20 comparisons to achieve the desired result.
Compare this to all other codes on this page, which make 99 outer loop iterations, 99 strlen() calls, 189 inner loop iterations, 189 str_split() calls, and 189 comparisons.
*faster still would be to remove the comparison inside of the strpos() block, add the x11 value to the array outside of the loop, then sort the array before displaying. Like this:
Code:
$d="5"; // must be declared as string for strpos()
$array[]=$d*11; // store only duplicate occurrence in range
for($x=1; $x<100; ++$x){
if(strpos($x,$d)!==false){ // if at least one $d is found
$array[]=$x;
}
}
sort($array);
echo implode(',',$array),"<br>Last number: ",end($array); // display
Here is alternative method that uses functional iteration:
Code:
$d=5;
$array=array_filter(range(1,99),function($v)use($d){return strpos($v,(string)$d)!==false;})+[$d*11];
sort($array); // zero-index the keys and position the appended value
echo implode(',',$array),"<br>Last number: ",end($array); // display
Output:
5,15,25,35,45,50,51,52,53,54,55,55,56,57,58,59,65,75,85,95
Last number: 95
Use rtrim then explode to get an array.
$b = 1;
$ab = 100;
for($b; $b < $ab; $b++){
$len = strlen($b);
$c = 0;
for($c; $c < $len; $c++){
$split = str_split($b);
if($split[$c] == 5){
echo $b .',';
}
}
}
$b = rtrim(',',$b);
$b = explode(',',$b);
$b = $b[count($b)-1];
This removes the last coma AND gives you the last value (as a string). You can always change the string back into an integer.
$b = 1;
$ab = 100;
$string = "";
for($b; $b < $ab; $b++){
$len = strlen($b);
$c = 0;
for($c; $c < $len; $c++){
$split = str_split($b);
if($split[$c] == 5){
$string .= $b .',';
}
}
}
$string = trim($string,",");
$pos = strripos($string,",");
echo substr($string,$pos + 1);
simply define a last variable:
$b = 1;
$ab = 100;
$last = 0;
for($b; $b < $ab; $b++){
$len = strlen($b);
$c = 0;
for($c; $c < $len; $c++){
$split = str_split($b);
if($split[$c] == 5){
if($last > 0){
echo ',';
}
echo $b;
$last = $b;
}
}
}
put the last value every time in $last.
and for coma, it checks if $last > 0 put coma before $b
You can also user these codes. Tested it and it worked.
$b = 1;
$ab = 100;
$hasValue = false;
for($b; $b < $ab; $b++){
$hasFive = false;
$len = strlen($b);
$c = 0;
for($c; $c < $len; $c++){
$split = str_split($b);
if($split[$c] == 5){
$hasFive = true;
}
}
if (!$hasValue && $hasFive) {
echo $b;
$hasValue = true;
}else if($hasFive){
echo ','.$b;
}
}

PHP-Trying to test for a 3-digit sequence of numbers within an array

I'm trying to determine if three sequential integers exist within an array. I've tested the code on several PHP sandbox sites, but as they don't allow the use of fgets, I've tested with an array that I have pre-filled with the 5 integers. The code works just fine under those circumstances, but fails miserably when run with an array filled by user-input. I'm not sure where the problem is, but any assistance would be greatly appreciated.
<?php
echo "Enter 5 Numbers:";
//{Write your code here
$arr = array();
for($i = 0; $i < 5; $i++){
$arr[$i] = trim(fgets(STDIN));
}
sort($arr);
function FindSeq($arr){
for($i = 0; $i < 3; $i++){
while($i < 3) {
$a = $i;
$b = $a + 1;
$c = $b + 1;
if(((($arr[$a]) + 1) === $arr[$b]) && ((($arr[$b]) + 1) === $arr[$c]) !== FALSE) {
exit("true");
}
else {
$i++;
}
}
}
}
FindSeq($arr);
echo "false";
?>
The lines are read in as strings, however you add + 1 which casts it to an integer. Then you use a strict comparison === with a string. Either use loose comparisons == or cast the values to an integer:
$arr[$i] = (int)trim(fgets(STDIN));
Here's a quick way to do this:
for($i = 2; $i=count($arr)-2; $i++)
if(($arr[$i-1] == $arr[$i]+1) && ($arr[$i+1] == $arr[$i] + 1))
return true;
return false;
The loop numbers account for your use of $arr[1] as the first element of the array. Something prettier would be more general.

Create dynamic for loop PHP function for all potential combinations

The code below will create an array for all possible combination that can occur when you have four different variables. The variables always need to equal 1. The for loops I have created work and I understand how to make this work for more variables, but can I make this dynamic? I need to have a function that has how many variables there are as a parameter. If there are three variables create the three forloops. If there are 10... create the 10 corresponding for loops to determine all possible combinations.
$anarray2 = array();
for( $a = 1; $a <= 97; $a++ ) {
for( $b = 1; $a + $b <=98 ; $b++ ) {
for( $c = 1; $a + $b + $c <= 99; $c++ ) {
$d = 100 - ( $a + $b + $c );
$var_1 = $a / 100;
$var_2 = $b / 100;
$var_3 = $c / 100;
$var_4 = $d / 100;
$anarray2[] = array( $var_1, $var_2, $var_3, $var_4 );
}
}
}
print_array( $anarray2 );
You're effectively looking to share out I identical items to N people in all of the different possible ways.
If there is one person (N==1), then there is only one way to do this - give that person all I items.
If there is more than one person (N>1), then we can consider how many items can be assigned to the first person, and then what the possible assignments are for the remaining N-1 people in each case.
This leads to a nice recursive solution. Firstly we solve the problem for N=1:
function assign($I, $N) {
$anarray = array();
if ($N == 1) {
$anarray[] = array($I);
} else {
// Coming up...
}
return $anarray;
}
Now we solve the problem for N=k (some constant) in terms of N=k-1 - that is, we solve the problem using the solution to a smaller problem. This will reach all the way back to the solution when N=1.
function assign($I, $N) {
$anarray = array();
if ($N == 1) {
$anarray[] = array($I);
} else {
for ($i = $I; $i < $I; $i++) {
foreach (assign($I - $i, $N - 1) as $subproblem) {
$anarray[] = array_merge(array($i), $subproblem);
}
}
}
return $anarray;
}
Something like that should do the job.

Why second passing php array element by reference generates wrong results?

I have this simple quicksort function (I got it from uncle "G")
function quicksort( &$list, $l , $r ) {
$i = $l;
$j = $r;
$tmp = $list[(int)( ($l+$r)/2 )];
do {
while( $list[$i] < $tmp )
$i++;
while( $tmp < $list[$j] )
$j--;
if( $i <= $j ) {
$w = $list[$i];
$list[$i] = $list[$j];
$list[$j] = $w;
//_swp($list[$i],$list[$j]);
$i++;
$j--;
}
}while( $i <= $j );
if( $l < $j )
quicksort($list, $l, $j);
if( $i < $r )
quicksort($list, $i, $r);
return $list;
}
And I have this little function to swap two variables.
function _swp(&$a,&$b){
$a=$a+$b;
$b=$a-$b;
$a=$a-$b;
}
How come I can't use _swp($a,$b) in quicksort function instead of this lines?
$w = $list[$i];
$list[$i] = $list[$j];
$list[$j] = $w;
If I comment out these 3 lines of code and enter call to _swp function I got bad results...
Please explain.
Best regards
the unexpected behavior is probably the "random" occurence of zeros in the sorted list. This happens because there is a special case while swapping:
if( $i <= $j ) {
// swapping here using references!
_swp($list[$i],$list[$j]);
$i++;
$j--;
}
The problem is found directly in the condition for swapping itself: if $i==$j then there are two references to the same variable. Thus calling _swp($list[$i],$list[$j]); will firstly add both variables $a = $a + $b. Considering $a and $b actually access the same variable content, $a and $b will then have the same value. In the next step $b = $a - $b will then be zero as $a is equal to $b. The third operation will leave the result to 0.
An easy solution for this is inserting another condition:
if( $i <= $j ) {
// ensure $i to be truly smaller than $j
if( $i < $j ) {
_swp($list[$i],$list[$j]);
}
$i++;
$j--;
}
I hope this will help you.
Cheers,
Fabian

How to get the length of longest string in an array

Say I have this array:
$array[] = 'foo';
$array[] = 'apple';
$array[] = '1234567890;
I want to get the length of the longest string in this array. In this case the longest string is 1234567890 and its length is 10.
Is this possible without looping through the array and checking each element?
try
$maxlen = max(array_map('strlen', $ary));
Sure:
function getmax($array, $cur, $curmax) {
return $cur >= count($array) ? $curmax :
getmax($array, $cur + 1, strlen($array[$cur]) > strlen($array[$curmax])
? $cur : $curmax);
}
$index_of_longest = getmax($my_array, 0, 0);
No loop there. ;-)
A small addition to the ticket. I came here with a similar problem: Often you have to output just the longest string in an array.
For this, you can also use the top solution and extend it a little:
$lengths = array_map('strlen', $ary);
$longestString = $ary[array_search(max($lengths), $lengths)];
Loop through the arrays and use strlen to verify if the current length is longer than the previous.. and save the index of the longest string in a variable and use it later where you need that index.
Something like this..
$longest = 0;
for($i = 0; $i < count($array); $i++)
{
if($i > 0)
{
if(strlen($array[$i]) > strlen($array[$longest]))
{
$longest = $i;
}
}
}
This way you can find the shortest (or longest) element, but not its index.
$shortest = array_reduce($array, function ($a, $b) {
if ($a === null) {
return $b;
}
return strlen($a) < strlen($b) ? $a : $b;
});

Categories