# Find index of double number delimiter

Posted on

Problem

I have a `String` with a `double` number. Unfortunately, the number is created on backends with different locals, so it could be both 101.02 and 101,02 (different delimiters). I need to get the position of this delimiter if it exists and get 0, if it is not.

I’ve come to two options:

``````int pos = amount.indexOf(',') == -1 ?
(amount.indexOf('.') == -1 ? 0 : amount.indexOf('.'))
: amount.indexOf(',');
``````

Second option with the same logic but different style:

``````int pos = amount.indexOf(',');
if (pos == -1) pos = amount.indexOf('.');
if (pos == -1) pos = 0;
``````

I do not need to have a `double` number from `String`, I just need the position of the delimiter to color the `String` (using the Android class `Spannable`).

Is there a cleaner way to achieve this goal? And which of these styles are better, in your opinion? Is there some way to use the `DecimalFormat` class to achieve the goal?

Solution

The problems with the first approach

``````int pos = amount.indexOf(',') == -1 ?
(amount.indexOf('.') == -1 ? 0 : amount.indexOf('.'))
: amount.indexOf(',');
``````

are that:

• It’s not that easily readable; the ternary operator has value when what is tested is simple enough. But when you start nesting them, it often degrades clarity.
• The index is calculated two times, one to test whether it is -1 or not, and the second time to return the value.

As such, the second approach

``````int pos = amount.indexOf(',');
if (pos == -1) pos = amount.indexOf('.');
if (pos == -1) pos = 0;
``````

is the most preferable between the two, mainly for clarity. You should consider putting that into a utility method.

There would be other approaches like using a regular expression, but another good one would to not traverse the string potentially 2 times, and instead of looking whether the string has a certain character, loop through each character and see if it is one of the potential delimiters. With Java 8, you could have

``````int pos = amount.chars().filter(c -> c == '.' || c == ',').findFirst().orElse(0);
``````

And you could write explicitly the `for` loop for Java ≤ 7.

Final point: having a position of 0 when neither `,` nor `.` are present in the String can be confusing; 0 is a valid index value for a string, and it can imply that the delimiter was the first character of the string. If you consider `".25"` (that could be a valid representation of a double number, the 0 before being implied), the code would consider this as if having no delimiter.

I prefer to make it obvious that `pos` is getting assigned a value, one way or another. To that end, a ternary expression would be good.

But the way you wrote your ternary condition is confusing. Inverting the condition would make it more readable.

``````int pos = amount.indexOf(',') >= 0 ? amount.indexOf(',') :
amount.indexOf('.') >= 0 ? amount.indexOf('.') : 0;
``````

I wouldn’t worry much about calling `.indexOf()` excessively. These strings are short, and performance is not likely to be an issue.

By biggest concern, though, is why the fallback value is 0. A result like that could indicate either an initial `.`, an initial `,`, or no decimal separator at all!

A word of caution: in some locales, the `,` or `.` could also be the thousands grouping separator, so there might not be a definitive way to know whether `"3,141"` should be interpreted as three thousand one hundred forty-one or as an approximation to π.