Given a hierarchy (like an outline) where each level is represented by an integer (e.g., the first level is 0, the second level is 1, and at any point you can start a new point at an earlier level), I want to reassign integers so that numbers are not skipped but at the same time respecting the original relationships. I've represented the input as an array:
$stuff = array(0,1,2,2,4,1,9,9,10,3,8,4);
And the desired output (when represented as an array) is:
$stuff = array(0,1,2,2,3,1,2,2,3,2,3,3);
The rules are:
- If the given value is the same as the nearest prior value, then the output value should be the same as the nearest prior's output value
- If the given value is higher (i.e., deeper) than the nearest prior value, then the output value should be one greater than the nearest prior's output value
- If the given value is lower (i.e., shallower) than the nearest prior value, then find the nearest prior value that is less than the given value and the output value should be one greater than that value.
The only way I've thought to do this is through recursion. And I can get it to work for all but the last case in my aforementioned input array. If I change the last case in my input array to a '5' rather than a '4' then it works.
Here is what I am trying:
<?php
$input = array(0,1,2,2,4,1,9,9,10,3,8,4);
$debug = false;
for ($i =0; $i < count($input); $i++) {
if ($debug) {
echo '<hr />Old level: '.$input[$i];
$newLevel = newLevel($input,$i,$input[$i],$debug);
echo '<br />New level: '.$newLevel.'<br /><br /><br /><hr />';
}
else {
echo 'Old level: '.$input[$i].'; New level: '.newLevel($input,$i,$input[$i],$debug).'<br />';
}
}
function newLevel($input, $index,$origValue,$debug) {
if ($index == 0) return 0;
else {
if ($input[$index] > $input[$index-1]) {
if ($debug) echo '<br />Orig value: '.$origValue.' in else/if';
return newLevel($input,$index-1,$origValue,$debug)+1;
}
elseif ($input[$index] == $input[$index-1]) {
if ($debug) echo '<br />Orig value: '.$origValue.' in else/elseif1';
return newLevel($input,$index-1,$origValue,$debug);
}
elseif ($input[$index] < $input[$index-1]) {
for ($i = $index-2; $i >= 0; $i--) {
if ($input[$index] == $input[$i]) {
if ($debug) echo '<br />Orig value: '.$origValue.' in else/elseif2/for/if';
return newLevel($input,$i,$origValue,$debug);
}
elseif ($input[$index] == ($input[$i] + 1)) {
if ($debug) echo '<br />Orig value: '.$origValue.' in else/elseif2/for/elseif';
return newLevel($input,$i,$origValue,$debug);
}
}
die ("Error with going to outer level -- should never hit this.");
}
}
}
?>
This is the output I want:
Old level: 0; New level: 0
Old level: 1; New level: 1
Old level: 2; New level: 2
Old level: 2; New level: 2
Old level: 4; New level: 3
Old level: 1; New level: 1
Old level: 9; New level: 2
Old level: 9; New level: 2
Old level: 10; New level: 3
Old level: 3; New level: 2
Old level: 8; New level: 3
Old level: 4; New level: 3
But the output I am getting has a "2" for the new level of the last line. Any help is greatly appreciated it.
min(prior_new_level, current_old_level)