# Generic function with same logic but different input structure

I have a data structure that looks like this:

interface Node {
originalWeight: number;
currentWeight: number;
}


where both properties are floats between 0 and 1.

To check if a node has been modified, I wrote a simple isNodeModified function:

isNodeModified(node: Node): boolean {
return Math.abs(node.originalWeight- node.currentWeight) > this.EPSILON;
}


where EPSILON is my tolerance.

However, I also need to do a very similar comparison in a slightly different scenario, which was originally handled like this:

if (Math.abs(event.value - node.originalWeight) > this.EPSILON) {
// do something
}


where event is another object with a value property.

To avoid duplication, I replaced both methods with something like the following:

isNodeModified(node: Node, event?: Event): boolean {
let original = node.originalWeight;
if (event) {
original = event.value;
}
return Math.abs(original - node.currentWeight) > this.EPSILON;
}


So that I can call isNodeModified(node) or isNodeModified(node, event) depending on what I need.

Is there a better / cleaner solution to this problem?

• Can you clarify what the purpose of event is?
Aug 23 '18 at 13:18
• @Adam it carries a value that will become the new originalWeight, but only if event.value !== currentWeight
– bugs
Aug 23 '18 at 13:28

The most concise way to write your function that's still very readable is this:

function isNodeModified(node: Node, event?: Event): boolean {
return Math.abs((event ? event.value : node.originalWeight) - node.currentWeight) > this.EPSILON;
}


If event is passed in, the event's value is used, otherwise node's originalWeight is used.

Ternary operators are amazing for condensing simple checks/if-statements into an inline operation. I recommend using them as much as possible as long as the result is still readable and not lengthy.

You could create a more general function which simple compares two values. Like:

hasDifference(oldValue: number, newValue: number, offset?: number): boolean {
const offsetToUse: number = offset === undefined ? this.EPSILON : offset;

return Math.abs(oldValue - newValue) > offsetToUse;
}

• offset?: number is better than offset: number | undefined as the second requires calling as hasDifference(oldV, newV, undefined) (assuming you have strict null checks on, which you should) Aug 23 '18 at 14:57
• changed it. @Gerrit0 - would that make hasDifference(oldV, newV, null) fail the === check? Aug 27 '18 at 12:23
• null !== undefined so yes. If you have strict null checks on though, Typescript will complain at compile time. Aug 27 '18 at 12:53