Repeat indecies of an array sequentially until it matches specified value - php

I am attempting to write a function that will cycle through an array and perform a task based on its value.
For example:
foreach ($content as $i => $c) {
cycle(array('<div class="row">', '', ''), $i)
$content;
cycle(array('', '', '</div>'), $i)
}
The function:
function cycle($cycles, $i) {
if ($cycles[$i] !== '') {
echo $cycles[$i];
}
}
This works fine if the length (count) of the array I am passing into cycle() matches the number of forloop iterations where I am calling the function. However, if the number of iterations is greater obviously I get errors.
Some of you may have guessed that I am trying to wrap content with a <div class="row"></div> at the specified number of iterations or cycles. I do not want to use modulo.
I want the cycle() function to ignore empty values and only output it's value if it is not an empty string or null.
Ideally, if my array is too short, I want to keep repeating its own indices starting at 0 until it's indices count matches $i.
So if i had an array such as $arr = array(a,b,c,d); amd and pass it to my cycle($arr) function and this runs in a forloop 7 times, I want to somehow fill in the array thusly: array(a,b,c,d,a,b,c) . so I can output the required number of opening and closing divs.
Any Suggestions?

Try this (working example)
function cycle($cycles, $i) {
$j=$i%count($cycles);
if ($cycles[$j] !== '') {
echo $cycles[$j];
}
}

Related

count the elements in array except of specific element

For example i have an array like this [-1,-1,-1,-1,-1,-1,2.5,-1,-1,8.3]
I want to count the element which are not -1 like except of the -1. Is there any function in php to get this ? One approach which i think is
Count the total array - count of the -1 in the array.
how can we achieve this.
P.S : please provide me a comment why this question deserve negative vote.
Like #MarkBaker said, PHP doesn't have a convenient function for every single problem, however, you could make one yourself like this:
$arr = [-1,-1,-1,-1,-1,-1,2.5,-1,-1,8.3];
function countExcludingValuesOfNegativeOne ($arr) {
return count($arr) - array_count_values(array_map('strval', $arr))['-1'];
}
echo countExcludingValuesOfNegativeOne($arr); // Outputs `2`.
It just counts the whole array, then subtracts the number of negative 1s in the array. Because PHP throws an error if any element in the array isn't a string 1 when using array_count_values, I've just converted all elements of the array to a string using array_map('strval', $arr) 2
you can use a for loop counter skipping for a specific number.
function skip_counter($array,$skip){
$counter = 0;
foreach ($array as $value) {
if ($value != $skip) $counter++;
}
return $counter;
}
then you call skip_counter($your_list, $number_to_be_skipped);

for loop does not traverse the whole array in PHP

I use PHP/7.2.0beta3. So I want to create a custom function to reverse an array in PHP. If the array is (1,2,3) the functions turns it to (3,2,1).
I thought I should use the array_pop, grab the last value of the array and pass it to another array.
The problem
Here is the code I wrote. Just copy it and run it as PHP. I dont know why it stops in the middle of the array and does not continue till the end.
$originalarray = range(0, 100, 5);//works
echo '<br> original array <br>';
print_r($originalarray); // 0-100, with 5 step
function customreverse($x){
echo '<br> original array in function <br>';
print_r($x); //works, 0-100, with 5 step
echo '<br> sizeof in function '.sizeof($x).'<br>'; //works, is 21
for($a=0; $a<sizeof($x); $a++){
$reversearray[$a] = array_pop($x);
echo '<br> reversearray in for loop <br>';
print_r($reversearray);//stops at 50
echo '<br> a in for loop <br>';
echo $a;//stops at 10
}
echo '<br> reverse in function <br>';
print_r($reversearray);////stops at 50
}
customreverse($originalarray);
The same problem occurs even if I replace sizeof with count. Or $a<sizeof($x) with $a<=sizeof($x). Why does it stop and does not traverse the whole array? What am I missing here?
Thanks
sizeof (or count) is evaluated on every iteration of the loop and the array shrinks on each iteration. You need to store the original count in a variable. For Example (I removed a few lines to focus on the issue):
<?php
$originalarray = range(0, 100, 5);//works
function customreverse($x){
$origSize=sizeof($x);
for($a=0; $a<$origSize; $a++){
$reversearray[$a] = array_pop($x);
}
return($reversearray);//stops at 50 (Now it doesn't)
}
print_r(customreverse($originalarray));
jh1711 properly explained that your loop ends early because the middle statement in for(statement1; statement2; statement3) gets executed each iteration, and because you're popping the original array within the loop, sizeOf() returns a smaller number each time.
You could compact your code a bit, by building your reverse array like so:
while(!empty($original)) $reverse[] = array_pop($original);
If you want to preserve key=>value bindings (meaning reverse keys as well, so that the same keys will bind to the same values), you could do:
while(!empty($original)):
$val = end($original); // set pointer at end of array
$reverse[key($original)] = $val;
endwhile;
If you want to modify the array in-place (not create a 2nd array), you could do:
for($i=0, $j=sizeof($original); $i < $j; $i++){
array_splice($original,$i,0,array_pop($original));
} // pop last element and insert it earlier in the array

Multidimensional sub array subtraction in PHP

Need subarray difference of below array
$arr = array(
array('s'=>'1','e'=>'3'),
array('s'=>'6','e'=>'7'),
array('s'=>'8','e'=>'9'),
array('s'=>'10','e'=>'14'),
array('s'=>'16','e'=>'17'),
)
if(arr[$arr[$i+1][s] - $i][e] <= 1){
//join them
}
else {
//save them as it is
}
Desired result should
$arr = array(
array('s'=>'1','e'=>'3'),
array('s'=>'6','e'=>'14'),
array('s'=>'16','e'=>'17'),
)
No consecutive (next S-E) should be 1
http://codepad.org/V8omMdn6 is where im struck at
See its like
iteration 0
6-3 = 3
so save array('s'=>'1','e'=>'3'),
iteration 1
8-7 = 1
array('s'=>'6','e'=>'9'), => discade in 2 as it
iteration 2
10-9 = 1
array('s'=>'6','e'=>'10'), => discade in 3 as it
iteration 3
10-9 = 1
array('s'=>'6','e'=>'14'),
iteration 4
16-14 = 4
array('s'=>'16','e'=>'17'),
$result = [];
foreach ($arr as $pair) {
if (empty($result) || $pair['s'] - end($result)['e'] > 1) {
$result[] = $pair;
} else {
$result[key($result)]['e'] = $pair['e'];
}
}
You might also use $last as key instead end() & key() for readability.
Using array pointer functions on $result shortens the code but uses some ugly hidden effects. end($result) returns last element of array (using key bracket with function result is possible since php5.3 I guess), but also sets the pointer, so key($result) will return correct key if needed.
While iterating you process last element of result array - this element might not be valid right away, but you don't need to look ahead. There are two scenarios for last element (+initial state condition for empty $result):
invalid: set e value from current item and process further
valid: leave it and push current item into results for further validation (unless that was the last one).
I took a very brief look at your codepen, I think what you want to achieve is to find out if the start time of a new session is within a given period from the end time of the last session, if so you would like to combine those sessions.
I think you confused yourself by trying to subtract start time of new session from end time of last session, it should be the other way round.
The way you worded the question made it even more confusing for people to understand.
If my interpretation of your question is correct, the below code should work with the test case you posted here.
function combineSession($arr){
$arrCount=count($arr)-1;
for ($i=0; $i<$arrCount; $i++){
//if the difference between s and e is less than or equal to one, then there is a consecutive series
if($arr[$i+1]['s']-$arr[$i]['e'] <= 1){
//assign the value of s at the start of a consecutive series to $temp
if (!isset($temp)){
$temp=$arr[$i]['s'];
}
//if consecutive series ends on the last sub_array, write $temp e pair to output
if ($i==$arrCount-1){
$output[]= array('s'=> $temp, 'e' => $arr[$arrCount]['e']);
}
}
//end of a consecutive series, write $temp and e pair to output, unset $temp
else if (isset($temp) && $i<$arrCount-1){
$output[]=array('s'=> $temp, 'e' => $arr[$i]['e']);
unset($temp);
}
//consecutive series ended at the second last sub-array, write $temp and e pair to output and copy key value pair of the last sub-array to output
else if ($i==$arrCount-1){
$output[]=array('s'=> $temp, 'e' => $arr[$i]['e']);
$output[]=$arr[$arrCount];
}
//not in a consecutive series, simply copy s e key value pair to output
else {
$output[]=$arr[$i];
}
}//end of for loop
print_r($output);
}//end of function
else if ($i==$arrCount-1){ $output[]=!isset($temp) ? $arr[$i] : array('s'=> $temp, 'e' => $arr[$i]['e']); $output[]=$arr[$arrCount]; }

How can I output 2 random values from an array?

I'm trying to make a simple PHP script for school. I need to output 2 random students from the array $leerlingen (Leerlingen = students).
It work's fine when I use echo $leerlingen within the foreach loop, but when I use the return statement it stops executing, because when return is used, it ends the function.
Code:
$leerlingen = array("tobias", "hasna", "aukje", "fred", "sep", "koen", "wahed", "anna", "jackie", "rashida", "winston", "sammy", "manon", "ben", "karim", "bart", "lisa", "lieke");
shuffle($leerlingen);
function maakGroepjes($leerlingen) {
$begin = 1;
foreach ($leerlingen as $leerling) {
if ($begin <= 2) {
echo $leerling;
$begin++;
}
}
}
echo maakGroepjes($leerlingen);
Can anyone tell me how to solve this problem?
You can return only one value inside a function, in this case is an array. I assume that the array have at least two values.
<?php
$leerlingen = array(
"tobias", "hasna", "aukje", "fred", "sep", "koen", "wahed", "anna", "jackie", "rashida", "winston", "sammy", "manon", "ben", "karim", "bart", "lisa", "lieke"
);
shuffle($leerlingen);
function maakGroepjes($leerlingen) {
//your result array
$result = array();
//Picking 2 random entries out of an array to $keys
$keys = array_rand($leerlingen, 2);
//Returning the array with two values
return array($leerlingen[$keys[0]], $leerlingen[$keys[1]]);
}
//assign the values to the vars
list($one, $two) = maakGroepjes($leerlingen);
//printing
echo $one . "<br>\n";
echo $two . "<br>\n";
?>
array_rand and other functions (rand) that rely on libc have a bad standard distribution. I'd always recommend using mt_rand() if you need it to be equally distributed, otherwise some entries will be heavily favored.
This is a good easy replacement for numerical arrays:
function array_mt_rand($array) {
return $array[ mt_rand( 0, count($array)-1 ) ];
}
$one = array_mt_rand($array);
$two = array_mt_rand($array);
You may need some extra checks if you have a small array and always want two distinct values though.
You could always try something like this.
function maakGroepjes($leerlingen) {
do {
$first_student = array_rand($leerlingen);
$second_student = array_rand($leerlingen);
} while ($leerlingen[$first_student] == $leerlingen[$second_student]);
return [$leerlingen[$first_studen], $leerlingen[$second_student]];
}
Which returns this.
Array
(
[0] => manon
[1] => winston
)
Also, the difference between a function printing/echo'ing information and returning information is pretty big.
You can't assign a variable to the echo statement inside of a function, whereas you could assign a variable to the return statement.
I would approach this a little differently.
function maakGroepjes($leerlingen) {
shuffle($leerlingen); // randomize the list of students
return array_chunk($leerlingen, 2); // break in into groups of two and return it
}
Then with
$groepjes = maakGroepjes($leerlingen);
you can generate all of the groups at once. No worries about repetition. This way if you need multiple groups, you can loop over the list of groups. If you really only need one group of two, then that will be
$groepjes[0];
which you can ouptut however you like. A very simple example:
foreach ($groepjes[0] as $student) echo "$student<br>";
Try this:
if ($begin <= 2) {
echo $leerling;
$begin++;
} else {
return
}
What this does is: every time through the loop, it looks at $begin. If it's less than or equal to two, it echoes that student and increments $begin. Otherwise, if it's greater than two, it returns, ending the function (and thus, the loop).
A perhaps better way to do it would be to just look at the ordinal directly:
foreach ($leerlingen as $ord => $leerling) {
echo $leerling;
if ($ord == 1) return;
}
Note the syntax in the loop definition. The "old =>" part sets the ordinal value as a variable as you loop through, letting you see which entry in the array you are currently on. So, this just loops through printing students. When it has printed the second student (remember, arrays are counted 0, 1, 2...) it returns.
Also, you probably don't want to echo maakGroepjes(). That function is what is echoing the student names. You probably don't want to echo the function result unless the function compiles the names into a string and returns the string or something.

Compare All strings in a array to all strings in another array, PHP

What i am trying to do is really but i am going into a lot of detail to make sure it is easily understandable.
I have a array that has a few strings in it. I then have another that has few other short strings in it usually one or two words.
I need it so that if my app finds one of the string words in the second array, in one of the first arrays string it will proceed to the next action.
So for example if one of the strings in the first array is "This is PHP Code" and then one of the strings in the second is "PHP" Then it finds a match it proceeds to the next action. I can do this using this code:
for ( $i = 0; $i < count($Array); $i++) {
$Arrays = strpos($Array[$i],$SecondArray[$i]);
if ($Arrays === false) {
echo 'Not Found Array String';
}
else {
echo 'Found Array String';
However this only compares the First Array object at the current index in the loop with the Second Array objects current index in the loop.
I need it to compare all the values in the array, so that it searches every value in the first array for the First Value in the second array, then every value in the First array for the Second value in the second array and so on.
I think i have to do two loops? I tried this but had problems with the array only returning the first value.
If anyone could help it would be appreciated!
Ill mark the correct answer and + 1 any helpful comments!
Thanks!
Maybe the following is a solution:
// loop through array1
foreach($array1 as $line) {
// check if the word is found
$word_found = false;
// explode on every word
$words = explode(" ", $line);
// loop through every word
foreach($words as $word) {
if(in_array($word, $array2)) {
$word_found = true;
break;
}
}
// if the word is found do something
if($word_found) {
echo "There is a match found.";
} else {
echo "No match found."
}
}
Should give you the result you want. I'm absolute sure there is a more efficient way to do this.. but thats for you 2 find out i quess.. good luck
You can first normalize your data and then use PHP's build in array functions to get the intersection between two arrays.
First of all convert each array with those multiple string with multiple words in there into an array only containing all words.
A helpful function to get all words from a string can be str_word_count.
Then compare those two "all words" arrays with each other using array_intersect.
Something like this:
$words1 = array_unique(str_word_count(implode(' ', $Array), 1));
$words2 = array_unique(str_word_count(implode(' ', $SecondArray), 1));
$intersection = array_intersect($words1, $words2);
if(count($intersection))
{
# there is a match!
}
function findUnit($packaging_units, $packaging)
{
foreach ($packaging_units as $packaging_unit) {
if (str_contains(strtoupper($packaging[3]), $packaging_unit)) {
return $packaging_unit;
}
}
}
Here First parameter is array and second one is variable to find

Categories