How to indicate a group in PHP for loop.

I'm wondering if this is a better way to do this.

$input = 29;
for ($i = 0; $i < $input; $i++) {
	if ($i <=10) $isGrp = 1;
	elseif ($i <=20) $isGrp = 2;
	elseif ($i <=30) $isGrp = 3;
	elseif ($i <=40) $isGrp = 4;
	elseif ($i <=50) $isGrp = 5;
	print 'The number ['.$i.'] is in group ['.$isGrp.']<br />';
} // 

Open in new window


What I'm needing to do is run through a changing group of numbers (actually corresponds to a list of numbers, but I've simplified the script above).  I want it to determine which group of ten numbers mu current number is.  I also would like the flexibility for this to change to groups of 8 or 5 and I would not like it to have a limit.

So in summary, to be able to sequentially go through a list of x numbers and determine which group the current number is in with a variable group size.
Paul KonstanskiProject SpecialistAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Ray PaseurCommented:
This is the quantiles design pattern.  Commonly used groupings include quartiles (four), quintiles (five), stanines (nine), percentiles (100), etc.  You make a distribution of the values and then chop the distribution up into the groups.  Here is my teaching example that illustrates the principles. You can experiment with the settings for q= and n= here:
http://iconoun.com/demo/quantiles.php

<?php // demo/quantiles.php

/**
 * Demonstration script for "quantiles": quartiles, quintiles, deciles, percentiles, etc.
 *
 * Algorithm:
 *    Create a data model - associative array of keys and values
 *    Sort ordered from highest to lowest
 *    Count the array
 *    Divide by quantile number giving the elements per group in each quantile
 *    Walk the array, marking the first quantile with a "1", the second quantile with a "2", etc
 *    Find the array element with the indicated key
 *    Display the number that indicates its quantile
 *
 * Man page references:
 * http://bmj.bmjjournals.com/cgi/content/full/309/6960/996
 * http://cancerweb.ncl.ac.uk/cgi-bin/omd?query=quantile&action=Search+OMD
 * http://en.wikipedia.org/wiki/Quantiles
 *
 * See also: http://en.wikipedia.org/wiki/Stanine
 */
error_reporting(E_ALL);
echo "<pre>";


// OUR TEST DATA MODEL MIGHT COME FROM A DATA BASE
$raw_data = array();
$raw_data['A'] = 1;
$raw_data['B'] = 2;
$raw_data['C'] = -3;
$raw_data['D'] = 4;
$raw_data['E'] = 5;
$raw_data['F'] = -6;
$raw_data['G'] = 7;
$raw_data['H'] = 8;
$raw_data['I'] = -9;
$raw_data['J'] = 10;
$raw_data['K'] = 11;
$raw_data['L'] = -12;
$raw_data['M'] = 13;
$raw_data['N'] = 14;
$raw_data['O'] = -15;
$raw_data['P'] = 16;
$raw_data['Q'] = 17;
$raw_data['R'] = -18;
$raw_data['S'] = 19;
$raw_data['T'] = 20;
$raw_data['U'] = 21;
$raw_data['V'] = 22;
$raw_data['W'] = 23;
$raw_data['X'] = 24;
$raw_data['Y'] = 25;
$raw_data['Z'] = 6;


// USE THE URL ARGUMENT OR CHOOSE A RANDOM LETTER
if (isset($_GET["q"]))
{
    $element = trim(strtoupper($_GET["q"]));
}
else
{
    $x = range('A', 'Z');
    shuffle($x);
    $element = current($x);
}

// USE THE URL ARGUMENT OR BY DEFAULT CHOOSE QUARTILES
$num = (isset($_GET["n"])) ? $_GET["n"] : 4;


// SORT THE DATA
arsort($raw_data);

// COUNT THE DATA
$kount = count($raw_data);
$tiles = intval(ceil($kount / $num));

// COPY THE ARRAY INSERTING THE QUANTILES
$quantiles = array();
$my_tile   = 1;
$my_tiles  = $tiles;
$negs = $pozs = 0;
foreach ($raw_data as $key => $val)
{
    if ($val < 0) $negs++;
    if ($val > 0) $pozs++;
    $quantiles[$key] = $my_tile;
    $my_tiles--;
    if ($my_tiles == 0)
    {
        $my_tiles = $tiles;
        $my_tile++;
    }
}


// REPORT THE STATISTICS
echo PHP_EOL . "COUNT OF ELEMENTS IN OUR DATA MODEL = $kount";
echo PHP_EOL . "COUNT OF NEGATIVE VALUES = $negs";
echo PHP_EOL . "COUNT OF POSITIVE VALUES = $pozs";
echo PHP_EOL . "NUMBER OF SUBSETS = $num";
echo PHP_EOL . "ELEMENTS PER SUBSET = $tiles";
echo PHP_EOL . "THE QUANTILE FOR $element IS {$quantiles[$element]}";
echo PHP_EOL;


// VISUALIZE THE GROUPED DATA
$n = 1;
foreach ($raw_data as $key => $val)
{
    if ($quantiles[$key] > $n)
    {
        $n = $quantiles[$key];
        echo PHP_EOL;
    }
    echo PHP_EOL . "$key $quantiles[$key] $val";
}

Open in new window

Marco GasiFreelancerCommented:
This seems to work:
$group = 6;
$input = 29;
$iterations = ceil($input / $group);
for ($x = 0; $x < $iterations; $x++)
{
	for ($i = 0; $i < $input; $i++) {
		if (($i > $group * ($x)) && ($i <= $group * ($x+1))) {
			$isGrp = $x+1;
			print 'The number ['.$i.'] is in group ['.$isGrp.']<br />';
		}
	}
}

Open in new window

Just change the value of $group to try different groups.

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Paul KonstanskiProject SpecialistAuthor Commented:
I was able to use Marco's code to get this to do what I wanted with only one slight change.

In the line 6 for loop the qualifier needs to be less than or equal to.  Otherwise it doesn't give the correct answer.

I've now created this function that I reference.

function quantile($curPos, $group, $totSize) {
	// $curPos = current position (to determine which group you are in)
	// $group = the size iterations of the group
	// $totSize = total size of sample to knoww when you're done.
	$iterations = ceil($totSize / $group);
	if ($curPos > $totSize) return $iterations;
	elseif (numbIt($curPos, "not")) return 1;

	for ($x = 0; $x < $iterations; $x++) {
		for ($i = 0; $i <= $totSize; $i++) {
			if (($i > $group * ($x)) && ($i <= $group * ($x+1))) {
				$isGrp = $x+1;
				if ($curPos == $i) return $isGrp;
			}
		} // for ($i = 0; $i < $totSize; $i++) {
	} // for ($x = 0; $x < $iterations; $x++) {
	return 0; // if you get this far it is an error and it returns zero
 } // function quantiles

Open in new window

Marco GasiFreelancerCommented:
Do you mean that this
for ($i = 0; $i < $input; $i++) {

Open in new window

should be
for ($i = 0; $i <= $input; $i++) {

Open in new window

?
But this way, if $input is 29, starting the loop at 0 you get 30 element, not 29. If this is what you want, well, but I did the code in order to allow to use as input the exact value of the desired return amount.
Anyway, I'm glad to help you :-) Cheers
Paul KonstanskiProject SpecialistAuthor Commented:
Thanks for the help. I can now reference this in the multiple places I need it.

Thanks.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
PHP

From novice to tech pro — start learning today.