views:

107

answers:

3

Suggestions for an updated title are welcome, as I'm having trouble easily quantifying what I'm trying to do.

This is a web-based form with PHP doing the calculations, though this question probably has an algorithmic or language agnostic answer.

Essentially, there is an Amount field and a Charge Code field. The Charge code entered represents a short-hand for several 'agents' to whom the Amount is divided by. Most cases are single letters, however there are a couple cases where this varies, and gives a bit of trouble.

Basically, A = AgentType1, J = AgentType2, L = AgentType3, and as paperwork and user requirements would have it, "A2" is also a valid replacement for "J".

So an amount of 50 and a Charge Code of "AJ" would result in the Amount being divided by 2 (two agents) and dispersed accordingly. The same for a string like "AA2".

I have currently set up process (that works) that goes like this:

Divide = 0;
RegEx check for AgentType1 in Charge Code: 
 Divide++;
 Set This-AgentType-Gets-Return; 
RegEx check for AgentType2 in Charge Code: 
 Devide++;
 Set This-AgentType-Gets-Return;
... etc ...

Then I divide the Amount by the "Divide" amount, and the result gets divvied up to each AgentType present in the Charge Code.

I know there must be an easier/simpler way to implement this, but it's not coming to me at the moment.

Is there a way to quickly derive the number of AgentTypes involved in the Charge Code, and which they are?

+1  A: 

Can you change the charge code field to an array of fields? Something like:

<input type="hidden" name="agent[]" value="A" />

for all your agents would let you do:

$divide = count($_POST["agent"]);
foreach($_POST["agent"] as $agent) {
    $sum = $_POST["amount"] / $divide;

    //do other stuff
}
davethegr8
+1  A: 

I would probably just do something simple like this:

$valid_codes = array('A', 'J', 'L');

// deal with the special A2 case first, to get it out of the string
// this code could be generalized if more special cases need to be handled
if (stripos($charge_code, 'A2') !== FALSE)
{
 $found['J'] = true;
 str_ireplace('A2', '', $charge_code);
}

foreach ($valid_codes as $code)
{
 if (stripos($charge_code, $code) !== FALSE) // if the code was in the string
 {
  $found[$code] = true;
 }
}

Now you can get the number you need to divide amount by with count($found), and the codes you need to divide between with array_keys($found).

Chad Birch
+1 no need to try to shoehorn regex into it! Perhaps this could be done as a single loop replacing strings, and put ‘A2’ at the front of the list to be tested first?
bobince
Could be done that way as well, but with a single loop it would require some processing afterwards to remove the $found['A2'] entry and transfer it into $found['J'], since it's basically just an alias.
Chad Birch
This is very similar to what's already happening. The reason RegEx was originally used was to not have to check for an 'A2' before 'A' - the code works without regard to the order the operations happen.
anonymous coward
A: 

Couldn't you match the string by something like this regex

^([A-Z]\d*)*$

and then work through the generated match list? The divisor would just be the length of this list (perhaps after removing duplicates).

For mapping symbols to Agents (why AgentTypes?), you could use a simple associative list, or a hashmap (I don't know what kind of constructs are easiest available in PHP).

Svante