Ranking/Position on value of array in PHP - php

I have an array with these values, Array ( [0] => 12 [1] => 17 [2] => 5 [3] => 27 [4] => 5 ) and I need to find out ranking/position of each value
ie,
for 27 - Rank 1
for 17 - Rank 2
for 12 - Rank 3
for 5 - Rank 4
for 5 - Rank 4 (duplicate value in the array)
and these need to be in the same order as the array, so that output should be as follow
12 - Rank 3
17 - Rank 2
5 - Rank 4
27 - Rank 1
5 - Rank 4

This should work (including duplicate values having the same rank):
$values = array();
$values[0] = 5;
$values[1] = 12;
$values[2] = 19;
$values[3] = 9;
$values[4] = 5;
$ordered_values = $values;
rsort($ordered_values);
foreach ($values as $key => $value) {
foreach ($ordered_values as $ordered_key => $ordered_value) {
if ($value === $ordered_value) {
$key = $ordered_key;
break;
}
}
echo $value . '- Rank: ' . ((int) $key + 1) . '<br/>';
}

try this
$array = Array ( "0" => 12 , "1" => 17 , "2" => 5, "3" => 27, "4" => 5 );
$i=1;
foreach($array as $key=>$values)
{
$max = max($array);
echo "\n".$max." rank is ". $i."\n";
$keys = array_search($max, $array);
unset($array[$keys]);
if(sizeof($array) >0)
if(!in_array($max,$array))
$i++;
}
Demo

Just came across this topic while looking for a nice solution for myself. Just drop this here for the future. What I'm using is the following function:
/* Assign rank to each value of the array $in.
* Args:
* in (array): Array containing as set of numeric values.
*
* Returns:
* Returns an array of the same length with ranks. Highest
* values of $in get rank 1, lower values get higher ranks.
* The same values are attributed to the same ranks.
*/
function array_rank( $in ) {
# Keep input array "x" and replace values with rank.
# This preserves the order. Working on a copy called $x
# to set the ranks.
print "input\n";
print_r($in);
$x = $in; arsort($x);
print "sorted\n";
print_r($x);
# Initival values
$rank = 0;
$hiddenrank = 0;
$hold = null;
foreach ( $x as $key=>$val ) {
# Always increade hidden rank
$hiddenrank += 1;
# If current value is lower than previous:
# set new hold, and set rank to hiddenrank.
if ( is_null($hold) || $val < $hold ) {
$rank = $hiddenrank; $hold = $val;
}
# Set rank $rank for $in[$key]
$in[$key] = $rank;
}
print "ranking result\n";
print_r($in);
return $in;
}
$a = array(140,180,180,100);
array_rank( $a );
The print statements (development) return the following:
input
Array
(
[0] => 140
[1] => 180
[2] => 180
[3] => 100
)
sorted
Array
(
[2] => 180
[1] => 180
[0] => 140
[3] => 100
)
ranking result
Array
(
[0] => 3
[1] => 1
[2] => 1
[3] => 4
)
In case you want to have a reverse ranking (lower values are better) simply replace arsort with asort. In my case I am ranking points, the higher the better. The array (140,180,180,100) gets the ranks (3,1,1,4). Players with the same amount of points get the same rank (in this case rank 1) while rank 2 is left out.

You can probably sort the array by the values:
$ranked = sort($arrayValues);
after this, you can do a for loop, looping through the $ranked array, then printing the arrays in order:
for($i = 0; $i < length($ranked); $i++){
for($j = 0; $j < length($arrayValues); $j++){
if($arrayValues[$i] == $sorted[$j]){
echo $arrayValues[$i] . ' has rank ' . $j;
}
}
}

one problem you have is that you want some return value that has 2 times an identical value and key (5=>rank4). So you cannot do an array with ranks as key nor with values as key. In this example i simply made a 2 dimensional array.
<?php
error_reporting(E_ALL | E_STRICT);
ini_set('display_errors', 1);
// your original input
$original = array(12, 17, 5, 27, 5);
// strip duplicates as they are ranked equally
$rankings = array_unique($original);
// apply some sorting so that the ranks are now given by the keys.
rsort($rankings);
// now just use the origincal array and lookup the rankings for each value
$return = array();
foreach($original as $value)
{
$rankedValue = array();
$rankedValue['value'] = $value;
$rankedValue['rank'] = array_search($value, $rankings) + 1;
$return[] = $rankedValue;
}
var_dump($return);

Related

I want to make a key value pair of numeric array in PHP on the base of index

foreach($manualsArray as $manuls){
for($i=0;$i<=count($manuls);$i++){
if($i/2 == 0){
$manuls = 23;
print($manuls);
}
else{
$manualsArray= 98;
print($manualsArray);
}
print($manualsArray);
}
}
I want to create key value pairs according to index like 0 is key 1 is value 2 is key 3 is value and so on.
the sample input is write below
Array
(
[0] => Array
(
[0] => Faucet Centers
[1] => 6, 4, 13, 12, 7, 10, 14, 16, 8, 5, 9, 15, 11 in.
[2] => Flow Rate (GPM)
[3] => 1.2
[4] => Height
[5] => 5.875 in.
[6] => Max Deck Thickness
[7] => 2.25 in.
[8] => Spout Height
[9] => 3.625 in.
[10] => Spout Reach
[11] => 5 in.
)
)
You can achieve this by changing your loop to increment by 2 each time and take $i as the key and $i+1 as the value...
$output = [];
foreach($manualsArray as $manual){
$m = [];
for ( $i = 0; $i < count($manual); $i+=2 ) {
$m [$manual[$i]] = $manual[$i+1];
}
$output [] = $m;
}
print_r($output);
you can use array_chunk()
foreach($manualsArray as $manuls){
foreach( array_chunk($manuls, 2) as $pair) {
echo 'key: ' . $pair[0] . ' is value: '. $pair[1] . "<br>/n";
}
}
or if you want an associative array
$result_array = [];
foreach($manualsArray as $manuls){
foreach( array_chunk($manuls, 2) as $pair) {
$result_array[] = [$pair[0] => $pair[1]];
}
}
var_export($result_array);
https://www.php.net/manual/en/function.array-chunk.php
Use modulo for that:
<?php
$newarray = array();
foreach($yourarray[0] as $id => $val){
if($id % 2 == 0){
$last_index = $val;
}else{
$newarray[$last_index] = $val;
}
}
?>
I assume that your array is the one you have given, so it's 2-dimensional.
If not, use $yourarray instead of $yourarray[0].

Split array but sum of each array not to exceed a max value else push to next array index

I have two arrays, Array 1 being a donor array which has a series of values (not necessarily equal values as in my example). Array 2 is the desired result and would store a series of sub arrays with values from Array 1 where each sub array's total sum would not exceed 25. If it does, the excess would get pushed to the next index in Array 2 where the rules would also apply.
Donor array (Array 1):
$a1=array(10,10,10,10,10,10,10,10,10,10);
Desired output (Array 2):
Array
(
[0] => 10,10,5
[1] => 5,10,10
[2] => 10,10,5
[3] => 5,10,10
)
Here the code I tried but it gets an error:
Notice: Undefined offset: 10...etc.
$a1=array(10,10,10,10,10,10,10,10,10,10);
$a2=array();
$count=count($a1);
for($i=0;$i<$count;$i++){
$a2count=array_sum($a2);
if($a2count>25){
$i=$i+1;
$a2[$i]=$a1[$i];
}
else{
$a2[$i]=$a1[$i];
}
}
print_r($a2);
I don't know what logic to implement and get result I'm looking for.
Mayhaps something like this will work for you. I will notate so it's not just a copy-and-paste answer. Maybe someone will get some insight on it to improve it in the future:
function slitArray($a1,$num = 25)
{
# Used to store the difference when the value exceeds the max
$store = 0;
# Storage container that will be built using sums/diffs
$new = array();
# Loop through the main array
foreach($a1 as $value) {
# If the last key/value pair in our return array is an array
if(is_array(end($new)))
# Add up the values in that array
$sum = array_sum(current($new));
else
# If not array, no values have been stored yet
$sum = 0;
# This just gets the last key
$count = (count($new)-1);
# Assign last key
$i = ($count <= 0)? 0 : $count;
# If the sum of the current storage array plus the value
# of the current array is greater than our max value
if(($sum + $value) > $num) {
# Take max and remove the current total of storage array
$use = ($num-$sum);
# Take what's left and remove it from the current value
$store = ($value-$use);
# If the current stored value (the value we want to push to
# the next storage k/v pair) is more than the max allowed
if($store > $num) {
# Takes a value, checks if it's greater than max,
# and if it is, breaks the value up by max as a divider
$divide = function($store,$num)
{
if($store > $num) {
$count = ceil($store/$num);
for($i=0; $i<$count; $i++) {
$new[] = ($store > $num)? $num : $store;
$store -= $num;
}
return $new;
}
else
return array($store);
};
# This should either be an array with 1 or more values
$forward = $divide($store,$num);
# Do a look forward and add this excess array into our
# current storage array
$a = $i;
foreach($forward as $aVal) {
$new[$a+=1][] = $aVal;
}
}
# If the store value is less than our max value, just add
# it to the next key in this storage array
else {
$new[$i+1][] = $store;
# Reset the storage back to 0, just incase
$store = 0;
}
}
# Set the current "use" value as the current value in our
# from-array. Since it doesn't exceed the max, it just gets
# added to the storage array
else
$use = $value;
# Sometimes the math makes $use 0, keep that out of the
# storage array. The $use value is the current value to add at
# the time of iteration. Previous storage values are added as
# future-keys
if($use > 0)
$new[$i][] = $use;
}
# Return the final assembled array
return $new;
}
# To use, add array into function
$a1 = array(10,10,10,10,10,10,10,10,10,10);
# to split using different max value, just add it to second arg
# example: slitArray($a1,20);
print_r(slitArray($a1));
Gives you:
Array
(
[0] => Array
(
[0] => 10
[1] => 10
[2] => 5
)
[1] => Array
(
[0] => 5
[1] => 10
[2] => 10
)
[2] => Array
(
[0] => 10
[1] => 10
[2] => 5
)
[3] => Array
(
[0] => 5
[1] => 10
[2] => 10
)
)
An array input of:
$a1 = array(23,2,71,23,50,2,3,4,1,2,50,75);
Gives you:
Array
(
[0] => Array
(
[0] => 23
[1] => 2
)
[1] => Array
(
[0] => 25
)
[2] => Array
(
[0] => 25
)
[3] => Array
(
[0] => 21
[1] => 4
)
[4] => Array
(
[0] => 19
[1] => 6
)
[5] => Array
(
[0] => 25
)
[6] => Array
(
[0] => 19
[1] => 2
[2] => 3
[3] => 1
)
[7] => Array
(
[0] => 3
[1] => 1
[2] => 2
[3] => 19
)
[8] => Array
(
[0] => 25
)
[9] => Array
(
[0] => 6
[1] => 19
)
[10] => Array
(
[0] => 25
)
[11] => Array
(
[0] => 25
)
[12] => Array
(
[0] => 6
)
)
Here you go: The logic is not so hard. Hope it helps.
<?php
$a1=array(10,10,10,10,10,10,10,10,10,10);
$a2 = [];
$a3 = [];
$m = 0;
for($i = 0; $i < count($a1); ++$i){
$m += $a1[$i];
if($m > 25){
$n = $m % 25;
if(array_sum($a2) != 25){
$a2[] = $n;
}
$a3[] = implode(',', $a2);
$a2 = [];
$m = $n;
$a2[] = $n;
} else{
$a2[] = $a1[$i];
}
}
$a3[] = implode(',', $a2);
print_r($a3);
?>
The final code for this question
<?php
function slitArray($a1,$num = 25)
{
$store = 0;
$new = array();
foreach($a1 as $value) {
if(is_array(end($new)))
$sum = array_sum(current($new));
else
$sum = 0;
$count = (count($new)-1);
$i = ($count <= 0)? 0 : $count;
if(($sum + $value) > $num) {
$use = ($num-$sum);
$store = ($value-$use);
if($store > $num) {
$divide = function($store,$num)
{
if($store > $num) {
$count = ceil($store/$num);
for($i=0; $i<$count; $i++) {
$new[] = ($store > $num)? $num : $store;
$store -= $num;
}
return $new;
}
else
return array($store);
};
$forward = $divide($store,$num);
$a = $i;
foreach($forward as $aVal) {
$new[$a+=1][] = $aVal;
}
}
else {
$new[$i+1][] = $store;
$store = 0;
}
}
else
$use = $value;
if($use > 0)
$new[$i][] = $use;
}
return $new;
}
$a1 = array(10,20,30,40,50,60);
$arr=slitArray($a1);
print_r($arr);
?>
Let me help you a bit using Pseudocode:
ar1 = {10,10,10,20,40,[0]=>1,[0]=>3,[0]=>4};
ar2 = new array (ar.length) \\ worst case
int c = 0; \\current
foreach (ar1 as $value){
ar2 [c]+=ar1[i];
if (ar2 [c]>25){ c++;}
}
Logic behind the code:
Add the value of ar1[i] to the current ar2 value till it passes your limit (25 in this case). If it exceeds you boundary, than move to the next value in the goal array. The worst case would be, that every value is over 25, so it would be an exact copy of the original array.
Here the php code:
$ar1=array(10,10,10,10,10,10,10,10,10,10);
$ar2 = array(0,0,0,0,0,0,0,0,0,0);
$c = 0;
foreach( $ar1 as $key => $value ){
$ar2[$c]=$value+$ar2[$c];
if ($ar2[$c]>25){$c++;}
}

How can I determine two numbers that are more close than others in an array

I have this array:
$arr = array (20, 1, 5, 10, 7, 16);
I would like to get 5 and 7. Because these are more close to each other than other items. In other word the difference between them is the lowest number:
7 - 5 = 2 // 2 is lowest number as the difference between all array's items
How can I do that?
$keep = $arr[0];
$diff = $arr[1] - $arr[0];
foreach ($arr as $item) {
if ( ($keep - $item) < $diff && $keep != $item ) {
$diff = $item;
}
}
My code is incomplete, Because it just compares first item with other items.
Explanation
So to get the two numbers in an array which are the closest to each other you have to compare each value with each other value. But you don't have to compare them with themselves and to the previous ones which you already compared.
To calculate how many comparisons you have to do you can use the binomial coefficient:
(n) n!
(k) → ─────────────
k! * (n - k)!
Where n is the total amount of elements and k how many you pick
And in your example this would mean:
n = 6 //Array elements
k = 2 //Two values which you compare
6! 720
───────────── → ───────────── = 15 comparison
2! * (6 - 2)! 2 * 24
Visualized
20 , 1 , 5 , 10 , 7 , 16 //Array values
↓ ↑ ↑ ↑ ↑ ↑
└────┴───┴───┴────┴───┘ //20 compared to all values, except itself
↓ ↑ ↑ ↑ ↑
└───┴───┴────┴───┘ //1 compared to all values, except itself + [20]
↓ ↑ ↑ ↑
└───┴────┴───┘ //5 compared to all values, except itself + [20, 1]
↓ ↑ ↑
└────┴───┘ //10 compared to all values, except itself + [20, 1, 5]
↓ ↑
└───┘ //7 compared to all values, except itself + [20, 1, 5, 10]
//16 compared to all values, except itself + [20, 1, 5, 10, 7]
Now to do this in code we need 2 loops to loop over the entire array for each value of the first loop. But as we already said we can ignore the value itself and the previous values, so for this we use 2 for loops and set the key, for the inner loop, to be the outer key + 1.
for($key = 0, $length = count($arr); $key < $length; $key++){
for($innerKey = $key + 1; $innerKey < $length; $innerKey++){
//↑ Skipping the previous values and the value itself
}
}
In the inner loop itself we just need to access the current value of the outer loop and get the difference compared to the value of the inner loop. That this also works with negative numbers we just wrap it into an abs() call to make the difference always positive.
Then we just check if the difference is smaller than the smallest difference which we already found, saved in $nearest. (We initialized $nearest by the difference of the biggest and smallest value of the array + 1):
if( ($diff = abs($arr[$keys[$key]] - $arr[$keys[$innerKey]])) < $nearest)
If the difference is smaller than the smallest difference which we already found, we write the two values into an array and set the new smallest difference:
$result = [$arr[$keys[$key]], $arr[$keys[$innerKey]]];
$nearest = $diff;
Code
<?php
$arr = [20, 1, 5, 10, 7, 16];
$keys = array_keys($arr);
$nearest = max($arr) - min($arr) + 1;
$result = [];
for($key = 0, $length = count($arr); $key < $length; $key++){
for($innerKey = $key + 1; $innerKey < $length; $innerKey++){
if( ($diff = abs($arr[$keys[$key]] - $arr[$keys[$innerKey]])) < $nearest){
$result = [$arr[$keys[$key]], $arr[$keys[$innerKey]]];
$nearest = $diff;
}
}
}
print_r($result);
?>
Output
[5, 7]
PHP usort is used here, as a note it is implemented with quicksort.
$temp ==> Temporary array to store the two values and its differences while looping
$temp = [arr[$i] , arr[$j] , arr[$i]-arr[$j] ]
$arr = array (20, 1, 5, 10, 7, 16);
$temp=array();
for ($i = 0; $i < count($arr)-1; $i++)
{
$diff=0;
for ($j = $i+1; ($j < count($arr) && $i!=$j); $j++)
{
$diff=abs($arr[$i]-$arr[$j]); //finding difference &taking absolute
$temp[] = array($arr[$i],$arr[$j], $diff);
}
}
usort($temp,function ($a, $b) { return $b[2] < $a[2]; });//sort `$temp[]` in ascending order according to the difference value
list($x,$y,$d) = $temp[0]; //the first row of `$temp` contains values with the diff. is lowest
//and the values is stored to `$x` & `$y` and there difference in `$d`
echo "Related Values are $x and $y by $d";
Check results here http://ideone.com/pZ329m
Working
20 1 5 10 7 16 //inner loop -----------------------
| | | | | | $temp[]=[[20,1,19],[20,5,15],[20,10,10],...//$i=0 |// `20` is compared values from 1 onwards and the values and differences are stored in `$temp[]`
|___|____|___|___|___| //(eg., $temp=[20,1,|20-1|]) //$j=1,2,3,4,5↓
| | | | | [1,5,4],[1,10,9],... //$i=1 | `1` is compared with values from 5 onwards
|____|___|___|___| //$j=2,3,4,5 ↓outer loop
| | | | [5,10,5],[5,7,2],... //$i=2 | `5` is compared with values from 10 onwards
|___|___|___| //$j=3,4,5 ↓
| | | [10,7,3],[10,16,6] //$i=3 | `10` is compared with values from 7 onwards
|___|___| //$j=4,5 ↓
| | [7,16,9]] //$i=4 |`7` is compared with final value `16`
|___| //$j=5 ↓
After getting $temp[] , it's sorted in ascending order according to the differences .
Then the first row of $temp[] gives our desired result .
Whats inside $temp[]
Array
(
[0] => Array
(
[0] => 7
[1] => 5
[2] => 2
)
[1] => Array
(
[0] => 7
[1] => 10
[2] => 3
)
[2] => Array
(
[0] => 16
[1] => 20
[2] => 4
)
[3] => Array
(
[0] => 5
[1] => 1
[2] => 4
)
[4] => Array
(
[0] => 10
[1] => 5
[2] => 5
)
[5] => Array
(
[0] => 16
[1] => 10
[2] => 6
)
[6] => Array
(
[0] => 7
[1] => 1
[2] => 6
)
[7] => Array
(
[0] => 16
[1] => 7
[2] => 9
)
[8] => Array
(
[0] => 10
[1] => 1
[2] => 9
)
[9] => Array
(
[0] => 10
[1] => 20
[2] => 10
)
[10] => Array
(
[0] => 16
[1] => 5
[2] => 11
)
[11] => Array
(
[0] => 7
[1] => 20
[2] => 13
)
[12] => Array
(
[0] => 5
[1] => 20
[2] => 15
)
[13] => Array
(
[0] => 16
[1] => 1
[2] => 15
)
[14] => Array
(
[0] => 1
[1] => 20
[2] => 19
)
)
As i comment to use 2 loop and a condition, i did the same thing. Just check it out and let me know.
$arr = array (20, 1, 5, 10, 7, 16);
$c = count($arr);
$ld = max($arr);
for($i = 0; $i < $c; $i++){
for($j = $i+1; $j < $c; $j++){
$abs = abs($arr[$i]-$arr[$j]);
if($abs < $ld)
$ld = $abs;
}
}
echo $ld; //2
if you need to know which two value has the difference then it is possible, just store them inside the if condition.
Well, quick and dirty... two loops, one condition
//$arr = array (20, 1, 5, 10, 7, 16); gives 5 and 7
$arr = array (-32,-15,4,6,-14,613,4,63,6,4);
$diff = INF;
foreach ($arr as $item0) {
foreach ($arr as $item1) {
$localdiff = abs($item0 - $item1);
if ( $localdiff > 0 && $localdiff < $diff ) {
$diff = $localdiff;
$keep0 = $item0;
$keep1 = $item1;
}
}
}
echo "Smallest distance was $diff, between $keep0 and $keep1";
Check it out on http://ideone.com/WdWOcb
use this
$arr = array (20, 1, 5, 10, 7, 16);
$temp = array();
foreach ($arr as $item1) {
foreach ($arr as $item2) {
$aV = abs($item1-$item2);
if(!in_array($aV, $temp) && $aV!=0)
$temp[$item1."-".$item2] =$aV;
}
}
$closest = array_keys($temp,min($temp));
list($first,$explode,$second) = $closest[0];
print "The two closest numbers are " . $first . " and " . $second;
$arr = array(20, 1, 5, 10, 7, 16);
$min = max($arr);
$closest = array();
foreach ($arr as $i) {
foreach ($arr as $j) {
if ($i != $j) {
$diff = abs($i - $j);
if ($min > $diff) {
$min = $diff;
$closest[0] = $i;
$closest[1] = $j;
}
}
}
}
print "The two closest numbers are " . $closest[0] . " and " . $closest[1];
It's not clear what happens in this situation:
$arr = array( 14, 20, 1, 5, 10, 7, 16 );
In above case you have two couples with 2 as difference ( 7-5, 16-14 ). Following code returns all relative values.
We execute the standard two nested loops for comparing all elements (main loop excluding last element, nested loop starting from main index +1), then if the difference between current values is lower than previously retrieved difference, we replace it; otherwise, if the difference is equal to previous difference, we append a new couple:
$result = array( 'sum' => INF, 'values'=> array() );
for( $i=0; $i < count( $arr )-1; $i++ )
{
for( $j = $i+1; $j < count( $arr ); $j++ )
{
$dif = abs( $arr[$i] - $arr[$j] );
if( $dif < $result['sum'] )
{
$result = array( 'sum' => $dif, 'values'=> array( array( $arr[$i], $arr[$j] ) ) );
}
elseif( $dif == $result['sum'] )
{
$result['values'][] = array( $arr[$i], $arr[$j] );
}
}
}
At this point, for above array sample, you have this result:
Array
(
[sum] => 2
[values] => Array
(
[0] => Array
(
[0] => 14
[1] => 16
)
[1] => Array
(
[0] => 5
[1] => 7
)
)
)
If you are interested in all value, simply you can find them in $result['values']. Otherwise, if you want (i.e.) min values (5 and 7), you can usort-it:
usort( $result['values'], function( $a, $b ) { return min($a)-min($b); } );
and use $result['values'][0]:
[0] => Array
(
[0] => 5
[1] => 7
)
try this
$arr = array (20, 1, 5, 10, 7, 16);
arsort($arr, SORT_NUMERIC);
$arr = array_values( $arr );
$min = 0;
foreach( $arr as $index => $number ){
if( isset($arr[$index+1]) ){
$diff = abs( $number - $arr[$index+1] );
if( $diff < $min || $min == 0 ){
$min = $diff;
$result = array( $number, $arr[$index+1] );
}
}
}
print_r( $result );

After for-loop, returned array is wrong

I have something like that:
$n = 2;
$items = array();
$result = array(); // new array with random items
$random_items = array_rand( $items, $n );
for( $f=0; $f<=$n; $f++ ) {
$result[] = $items[$random_items[$f]];
}
$items is sth like
Array ( [0] => file1.jpg [1] => file2.png [2] => file3.jpg ... and so on )
This is working OK... but if I set $n to 1 then the script is not working or working incorrectly!
If $n == 2 (or more) the result array have last element's value empty
Array ( [0] => 20141125-17826a4b34.png [1] => 20141125-27fe57561d.jpg [2] => )
If $n == 1 (exactly) the result array is like
Array ( [0] => [1] => )
The result array should be the same format as items array but only with $n random items.
Thanks in advance!
Working
if( $n > 1 ) {
for( $f=0; $f<$n; $f++ ) {
$result[] = $items[$random_items[$f]];
}
}
elseif( $n == 1 ) {
$result[0] = $items[$random_items];
}
You should $f < $n instead of $f <= $n
for( $f=0; $f < $n; $f++ ) {
$result[] = $items[$random_items[$f]];
}
Because, when you're using $f <= $n its running up to 0,1 (when, $n = 1) OR 0,1,2 (when $n = 2) and you're missing the last indexed element.
When picking only one entry, array_rand() returns the key for a random
entry(not array).Otherwise, an array of keys for the random entries is returned.
So, This means, when you're using $n = 1, then $random_items is just a value(not array). eg.
for $n = 1, $random_items = 4;
but for $n >= 2, $random_items = [1, 6, 3, 6];

Breaking an array into groups based on values

Using PHP, I'm trying to break an array up into multiple arrays based on groups of values. The groups are based on the values being between 1 and 5. But here's the hard part...
I need to loop through the array and put the first set of values that are between 1 and 5 in their own array, then the next set of values that are between 1 and 5 in their own array, and so on.
But each group WON'T always include 1,2,3,4,5. Some groups could be random.
Examples:
1,1,2,2,3,4,5 - this would be a group
1,2,3,4,4,4 - this would be a group
1,2,3,3,5 - this would be a group
2,2,3,3,5 - this would be a group
So I can't just test for specific numbers.
Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
[4] => 5
[5] => 1
[6] => 2
[7] => 3
[8] => 4
[9] => 4
[10] => 1
[11] => 1
[12] => 3
[13] => 4
[14] => 5
)
Any Ideas?
I would just check if the current value is larger than the previous value, and if yes, begin a new group.
$groups = array();
$groupcount = 1;
foreach( $array as $key=>$value )
{
if( $key > 0 ) // there's no "previous value" for the first entry
{
if( $array[$key] < $array[$key-1] )
{
$groupcount = $groupcount + 1;
}
}
$group[groupcount][] = $value;
}
Is this what you are looking for?
$groups = array();
$cur = array();
$prev = 0;
foreach ($numbers as $number)
{
if ($number < $prev)
{
$groups[] = $cur;
$cur = array();
}
$cur[] = $number;
$prev = $number;
}
if ($cur) $groups[] = $cur;
Untested. (Edit: corrected some obvious mistakes.)

Categories