# Refactoring Complex Conditionals To Conditional Look-ups

In a previous post, I demonstrated how you could refactor IF statements with straight x == y conditions to lambda maps. This is useful when we need to retain codes – literal values – and look up the appropriate action for each. (Think, for example, of the Mars Rover kata, where our rover accepts strings of characters representing instructions to turn ‘L’ and ‘R’ or move ‘F’ and ‘B’).

But what happens when the conditions aren’t straightforward? Consider this example that calculates postage for orders based on where the order is to be shipped, the weight of the order and the total price.

 function postage(order) { if(order.location === 'UK') { if (totalPrice(order) >= 100) { return 0; } if (totalWeight(order) < 1) { return 2.99; } if (totalWeight(order) >= 1 && totalWeight(order) < 3) { return 4.99; } if (totalWeight(order) >= 3) { return 6.99 } } if(order.location === 'EU') { if (totalWeight(order) < 1) { return 4.99; } if (totalWeight(order) >= 1 && totalWeight(order) < 3) { return 6.99; } if (totalWeight(order) >= 3) { return 8.99 } } }

Could we refactor this to something equally dynamic as a lambda map? Of course we could. All it takes is a loop.

 function match(conditions) { for (let i = 0; i < conditions.length; i++) { if (conditions[i]()) { return conditions[i](); } } return undefined; } function postage(order) { return match([ [() => order.location === 'UK', () => match([ [() => totalPrice(order) >= 100, () => 0], [() => totalWeight(order) < 1, () => 2.99], [() => totalWeight(order) >= 1 && totalWeight(order) < 3, () => 4.99], [() => totalWeight(order) >= 3, () => 6.99] ]) ], [() => order.location === 'EU', () => match([ [() => totalWeight(order) < 1, () => 4.99], [() => totalWeight(order) >= 1 && totalWeight(order) < 3, () => 6.99], [() => totalWeight(order) >= 3, () => 8.99] ]) ] ]); }

Using this approach, we can recursively compose conditional logic in a dynamic fashion, and with the judicious use of spacing, we can have our mappings read in a more tabular fashion. It also opens up the possibility of dynamically altering the rules – perhaps from a file, or based on some condition or triggered by an event (e.g., a promotional sale that removes postage on more orders). ## Author: codemanship

Founder of Codemanship Ltd and code craft coach and trainer

Posted on Categories refactoring