PHP endless loop, why? - php

Here is my code. I don't understand why am I in endless loop.
I think $check has to stop the loop when I make unique random values for my array.
<?php
$foo["blue"] = 0;
$foo["black"] = 0;
$foo["red"] = 0;
$foo["white"] = 0;
$check;
do
{
foreach($foo as &$val)
{
$val = rand(1,6);
}
$foo = array_unique($foo);
$check = count($foo);
}
while($check != 4);
echo '............................ <br>';
foreach($foo as $key=>$value)
{
echo $key . ' ' . $value . '<br>';
}
?>

The problem is that the first time through the loop there are some duplicates, so array_unique() reduces the array from 4 elements to 1, 2, or 3. The foreach loop can never make the array bigger again, because it's only looping over the elements that currently exist in the array. So once the array shrinks, it will never grow back to 4 elements, and $check != 4 will always be true.
You should get the original keys of the array and use that.
<?php
$foo["blue"] = 0;
$foo["black"] = 0;
$foo["red"] = 0;
$foo["white"] = 0;
$keys = array_keys($foo);
$check;
do
{
foreach($keys as $i)
{
$foo[$i] = rand(1,6);
}
$foo = array_unique($foo);
$check = count($foo);
}
while($check != 4);
echo '............................ <br>';
foreach($foo as $key=>$value)
{
echo $key . ' ' . $value . '<br>';
}
?>
DEMO

Personally, I wouldn't do it in a loop with such low entropy as it could take all day to finally match a random set.
A better way would be to generate a range and randomise that, then loop over your array and set the value.
<?php
$rand = range(1, 6);
shuffle($rand);
$foo["blue"] = 0;
$foo["black"] = 0;
$foo["red"] = 0;
$foo["white"] = 0;
$i=0;
foreach ($foo as $key => $value) {
$foo[$key] = $rand[$i];
$i++;
}
print_r($foo);
/*Array
(
[blue] => 1
[black] => 3
[red] => 2
[white] => 5
)
*/
https://3v4l.org/4hPku

Related

How to add string into array in PHP?

I have these for loop to determine consecutive number. What I achieve so far is to print the output in string.
$arr = [1,2,3,6,11,5,4,8,9,3];
for($start=0; $start<=count($arr); $start++){
for($end=$start+1; $end<=count($arr); $end++){
$total = $arr[$end] - $arr[$start];
if($total == 1){
echo 'Number is '.$arr[$start].','.$arr[$end].'<br/>';
} else {
echo '';
}
$arr[$start++];
}
}
My goal is to add the output into array.
I tried to use multidimensional array but no output display.
$arr = [1,2,3,6,11,5,4,8,9,3];
$arr3 = [];
for($start=0; $start<=count($arr); $start++){
for($end=$start+1; $end<=count($arr); $end++){
$total = $arr[$end] - $arr[$start];
if($total == 1){
$arr2 = array();
$arr2[] = $arr[$start].','.$arr[$end].'';
$arr3[] = $arr2;
} else {
}
$arr[$start++];
}
}
echo '<pre>';
print_r($arr3);
echo '</pre>';
exit;
Appreciate if someone can help me. Thanks.
you can simply use array functions, if sorting is important to you as #nice_dev said, you must sort your array before.
$arr = [1,2,3,6,11,5,4,8,9,3];
$cons = [] ;
while (array_key_last($arr) != key($arr)) {
if ((current($arr)+1) == next($arr)) {
prev($arr);
$cons[] = current($arr) . ',' . next($arr);
}
}
print_r($cons);
the output will be :
Array
(
[0] => 1,2
[1] => 2,3
[2] => 8,9
)
You can better sort() the input array first. This way, collecting all consecutive elements would get much simpler. If value at any index isn't +1 of the previous one, we add the $temp in our $results array and start a new $temp from this index.
Snippet:
<?php
$arr = [1,2,3,6,11,5,4,8,9,3];
$result = [];
sort($arr);
$temp = [];
for($i = 0; $i < count($arr); ++$i){
if($i > 0 && $arr[ $i ] !== $arr[$i - 1] + 1){
$result[] = implode(",", $temp);
$temp = [];
}
$temp[] = $arr[$i];
if($i === count($arr) - 1) $result[] = implode(",", $temp);
}
print_r($result);
Online Demo

how to use one array two times in an array php?

$a = array('a','b','c','d','e','f');
$b = array('1','2');
$count = 0;
$d = 0 ;
$input = array('ina', 'inb','inc');
foreach ($a as $key => $v) {
$count++;
echo $v;
echo $input[$key];
if ($count%3 == 0){
echo $b[$d++];
reset($input);
}
}
I want like this output
1
a-ina
b-inb
c-inc
2
d-ina
e-inb
f-inc
Actually I want $input two times in a foreach loop. $a have 6 items $input have 3 items and $b have 2 items. I need
To make it more applicable, Demo
$a = array('a','b','c','d','e','f');
$input = array('ina', 'inb','inc');
$loop = 1;
$input_length = count($input); // TODO process the length with 0 case.
foreach($a as $index => $value){
if(!($i = $index % $input_length)){
echo $loop . PHP_EOL;
$loop++;
}
echo $value . "_" . $input[$i] . PHP_EOL;
}
You're keeping a few variables that you don't really need as they can be derived from the $key value from $a. To get the output you want, you could do this:
$a = array('a','b','c','d','e','f');
$b = array('1','2');
$input = array('ina', 'inb','inc');
$len = count($input);
foreach ($a as $key => $v) {
$idx = $key % $len;
if ($idx == 0){
echo $b[floor($key/3)] . PHP_EOL;
}
echo $v . "-";
echo $input[$idx] . PHP_EOL;
}
Output:
1
a-ina
b-inb
c-inc
2
d-ina
e-inb
f-inc
Demo on 3v4l.org

All Data Store in one Array using php

while loop generates 12 digit number. Store this numbers outside the while loop in array.
for($i=1;$i<5;$i++){
$active_id='';
$count=0;
$active_code='';
$myarray = array();
while ( $count < 12 ) {
$random_digit = mt_rand(0, 9);
$active_id .= $random_digit;
$count++;
}
echo $active_id;
}
for($i=1;$i<5;$i++){
$active_id='';
$count=0;
$active_code='';
while ( $count < 12 ) {
$value .= mt_rand(0, 9);
$count++;
$active_id[$i] = $value;
}
unset($value);
$myarray[] = $active_id;
}
var_dump($myarray);
it generates an array with for numbers each having 12 digits.
You get a huge number because you just print the values one after the other. Do it like this, instead:
$nums = array();
for($i = 1; $i < 5; $i++){
$active_id='';
$count=0;
while ( $count < 12 ) {
$active_id .= mt_rand(0, 9);
$count++;
}
$nums[] = $active_id;
}
echo implode('<br>', $nums);
Outputs something like:
547806804306
795608578570
440070793444
942559796496
You can also use a loop to display the values, like so:
foreach($nums as $v){
echo $v . '<br>';
}
The output:
462186324671
222725884540
242904883364
589742052131
Note that I removed a couple variables that weren't really needed.

How to extract adjacent pair of words in associative array in php?

I have an associative array in PHP like this:
$weight["a"]=1;
$weight["b"]=4;
$weight["c"]=5;
$weight["d"]=9;
Here I want to calculate pair-wise difference between consecutive array elements, e.g.,
"b-a" = 3
"c-b" = 1
"d-c" = 4
How should this be computed?
Try this:
$i = 0;
foreach ($weight AS $curr) {
if ($i > 0) {
echo '"'.array_keys($weight)[$i].'-'.array_keys($weight)[$i-1].'" = '.($curr-$prev)."<br />";
}
$i++;
$prev = $curr;
}
Store keys on a temporary array where keys are integers on which you can easily get the next key, and use it to parse your main array.
$tmp_array = array();
foreach ($weight as $key => $val) {
$tmp_array[] = $key;
}
$array_length = count($tmp_array);
for ($i = 0; i < array_length - 2; ++$i) {
echo $weight[$tmp_array[$i+1]], '-', $weight[$tmp_array[$i]], ' = ', ($weight[$tmp_array[$i+1]] - $weight[$tmp_array[$i]], PHP_EOL;
}

PHP: how to do foreach and start from sixth element of collection?

is it possible to start a foreach loop from specific element [sixth element]?
im using this code:
<?php
$num=1;
foreach($temp_row as $key => $value) {
echo $num;
$num++;
}
?>
thanks :)
You can use for example array_slice()
$num = 5; //it will start from sixth element
foreach(array_slice($temp_row, $num) as $key => $value) {
echo $key.'=>'.$value.'<br>';
}
Not directly with a foreach(). The clue is in the each part of the name. It loops through all elements.
So how can we achieve it?
You could always just have an if() clause inside the loop that checks the key value before doing the rest of the work.
But if that's not workable for you, for whatever reason, I'd suggest using a FilterIterator to achieve this.
The FilterIterator is a standard PHP class which you can extend to create your own filters. The iterator can then be looped using a standard foreach() loop, picking up only the records that are accepted by the filter.
There are some examples on the manual page linked above that will help, but here's a quick example I've thrown together for you:
class SkipTopFilter extends FilterIterator {
private $filterNum = 0;
public function __construct(array $array, $filter) {
parent::__construct(new ArrayIterator($array));
$this->filterNum = $filter;
}
public function accept() {
return ($this->getInnerIterator()->key() >= $this->filterNum);
}
}
$myArray = array(13,6,8,3,22,88,12,656,78,188,99);
foreach(new SkipTopFilter($myArray, 6) as $key=>$value) {
//loop through all records except top six.
print "rec: $key => $value<br />";
}
Tested; outputs:
rec: 6 => 12
rec: 7 => 656
rec: 8 => 78
rec: 9 => 188
rec: 10 => 99
you could skip if counter is not 6th element...
<?php
$num=0;
foreach($temp_row as $key => $value) {
if( ++$num < 6 )
{
continue;
}
echo $num;
}
?>
Or with a for loop
$num = 1;
for($i=5; $i<= count($temp_row), $i++) {
echo $num;
$num++;
}
try this code:
$new_temp_row = array_slice($temp_row, 5);
foreach($new_temp_row as $key => $value) {
echo $value;
}
You may create new array with needed data part of origin array and work with it:
$process = array_slice ($temp_row, 5);
foreach($process as $key => $value) {
//TODO Your logic
}
Or you may skipp first siel elments:
<?php
$num=1;
foreach($temp_row as $key => $value) {
if ($num < 6) {
$num++;
continue;
}
//TODO Your logic
}
?>
I suggest you use a for look instead of a for each. You can then access both the key and value that are at i position inside your loop.
<?php
$num = 1;
$keys = array_keys( $temp_row );
for( $i = 5; $i < count( $temp_row ); $i++ ) {
$key = $keys[$i];
$val = $temp_row[$i];
echo $i;
}
?>
$i = 1;
foreach ($temp_row as $key => $value) {
if (($num = $i++) < 6) continue;
// Do something
}
Or
for ($i = 0; $i < 5; $i++) next($temp_row);
while(list($key, $value) = each($temp_row)) {
// Do something
}

Categories