2
$widgetsRequested = 2467; // Our magic variable - user input


  echo 'Original Number:';
    echo $widgetsRequested;
    echo '<br>';

    $widgetBatches = array("250", "500", "1000", "2000");
        rsort($widgetBatches);
        foreach ($widgetBatches as $key => $val) {
    } // Reverse sort values

    $processWidgetTotal = $widgetBatches; // Pass it on to process

function compareWidgets1($processWidgetTotal, $number) {    // run this once to compare
    sort($processWidgetTotal);
    foreach ($processWidgetTotal as $a) {
        if ($a >= $number) return $a;
    }
    return end($processWidgetTotal); 
}

echo 'Our Closest Matching Batch is: ';
echo $totalRemaining1 = compareWidgets1($processWidgetTotal, $widgetsRequested); // Go through and find the closest match within the widgetBatches array
echo '<br>';

echo 'Left To Allocate: ';
echo $newWidgetTotal1 = $widgetsRequested - $totalRemaining1; // Go through and find the closest match within the widgetBatches array
echo '<br>';

What I need to do is take the user input ($widgetsRequested) check it against the compareWidgets1 function (which checks the $widgetBatches array for the closest match) then echo that closest match, deduct it from the user input and loop again until the $widgetsRequested reaches 0 or the first negative result (i.e. -5).

I'm thinking i'll need a dowhile loop? but I can't get the function to sit right within it, help please?

Tom James
  • 33
  • 4

1 Answers1

0

This is how i solved you're question:

public $iterations = 0;

private function Widget($userinput)
{
    $this->iterations++;
    $widgetRequested = $userinput;
    $widgetBatches = array("250", "500", "1000", "2000");
    echo "Iteration " . $this->iterations;
    echo "<br/>";

    echo "Widget requested: " . $widgetRequested;
    echo "<br/>";

    $closest = $this->GetClosest($widgetBatches, $widgetRequested);
    echo "Closest: " . $closest;
    echo "<br/>";

    $widgetRemaining = $widgetRequested - $closest;
    echo "Remainder: " . $widgetRemaining;

    echo "<hr/>";
    if($widgetRemaining > 0)
    {
        $this->Widget($widgetRemaining);
    }
    else
    {
        echo "The value is now below or equaling zero: " . $widgetRemaining . "!";
    }
}

//Code is from: http://stackoverflow.com/questions/5464919/php-nearest-value-from-an-array
private function GetClosest(array $array, $value)
{
    $lowest = null;
    foreach($array as $val)
    {
        if($lowest == null || abs($value - $lowest) > abs($val - $value))
        {
            $lowest = $val;
        }
    }

    return $lowest;
}

**note: This is made in my current project, may need some additional changes regarding $this keywords.*

Basically what we are doing is getting the closest match, store this value. After that we subtract this with the result of closest and userinput. Then we do an if clause to see if were below zero or not. If not we call the function once again with the value we just generated.

Output:

Iteration 1
Widget requested: 2467
Closest: 2000
Remainder: 467

Iteration 2
Widget requested: 467
Closest: 500
Remainder: -33

The value is now below or equaling zero: -33!
Syntasu
  • 69
  • 7
  • Thanks!!! looking good and it seems in theory to work but my end it's not working, checking on a PHP Code Checker it seems to dislike the 'public' and 'private' functions however removing these and while the Checker says it works, my end nothing functions. – Tom James May 27 '15 at 09:32
  • As i (kinda) said in my answer, you still need to adopt the code to your environment/website. private/public is not even needed, only if you place it inside a class. and the $this-> variables need to be replaced if not using a class. – Syntasu May 27 '15 at 09:37
  • Ok thanks, looking back at the brief I think it needs to be lifted into MySQL now ... bah ... as it says the widgetBatches need to be added to and removed from which wouldn't be possible otherwise. – Tom James May 27 '15 at 10:06
  • Thats not too hard, just fetch and result from the database. Most SQL connectors have a method to convert a resultset to an array. In the Widget method you can just add another argument. Pass in a santized/normalized array (not assoc nor multi-dimensional) and the method should pick it up just fine. The only thing you need to do is to make a connection, fetch data, normalize the data and pass it in to the Widget method. Here is the PHP doc for fetching arrays: http://php.net/manual/en/mysqli-result.fetch-array.php – Syntasu May 27 '15 at 10:14
  • Right so i've set it up so that I can add to the batches table, remove from and list the table so that's all ok now. But trying to pull the data down as a numeric array isn't working for some reason, the only way I can get it to show is through an associative array which as you said, wont work for the Widget method. Any suggestions please? – Tom James May 27 '15 at 13:39
  • PHP has a very nifty function called "array_values($array)". This will strip off the key values (making it a non-associative array). This can now be passed into the Widget method (if im correct). – Syntasu May 27 '15 at 20:28