1
\$\begingroup\$

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?

asked Aug 23, 2018 at 12:24
\$\endgroup\$
2
  • \$\begingroup\$ Can you clarify what the purpose of event is? \$\endgroup\$ Commented Aug 23, 2018 at 13:18
  • \$\begingroup\$ @Adam it carries a value that will become the new originalWeight, but only if event.value !== currentWeight \$\endgroup\$ Commented Aug 23, 2018 at 13:28

2 Answers 2

1
\$\begingroup\$

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.

answered Aug 23, 2018 at 14:00
\$\endgroup\$
1
\$\begingroup\$

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;
}
answered Aug 23, 2018 at 13:26
\$\endgroup\$
3
  • 2
    \$\begingroup\$ 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) \$\endgroup\$ Commented Aug 23, 2018 at 14:57
  • \$\begingroup\$ changed it. @Gerrit0 - would that make hasDifference(oldV, newV, null) fail the === check? \$\endgroup\$ Commented Aug 27, 2018 at 12:23
  • 1
    \$\begingroup\$ null !== undefined so yes. If you have strict null checks on though, Typescript will complain at compile time. \$\endgroup\$ Commented Aug 27, 2018 at 12:53

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.