M Ansyori
M Ansyori

Reputation: 488

How to join string and number suffixes together in Android/Java?

Well, I need to split a string, number, and the other string in order to get results with suffixes. I have this example string:

Recharge Data 100000 only in your location

I was able to get this Log from the string above with this function in Java:

E/numberMatches: numberMatches: 10000

E/formattedString: formattedString: 10k

Here is the code of convert to suffixes string function:

// code in GeneralUtils.java file

public static String extractNumber(final String str) {
  if (str == null || str.isEmpty()) return "";
  StringBuilder sb = new StringBuilder();
  boolean found = false;
  for (char c: str.toCharArray()) {
    if (Character.isDigit(c)) {
      sb.append(c);
      found = true;
    } else if (found) {
      break;
    }
  }
  return sb.toString();
}

private static final NavigableMap < Long, String > thousandSuffixes = new TreeMap < > ();

static {
  thousandSuffixes.put(1 _000L, "k");
  thousandSuffixes.put(1 _000_000L, "M");
  thousandSuffixes.put(1 _000_000_000L, "G");
  thousandSuffixes.put(1 _000_000_000_000L, "T");
  thousandSuffixes.put(1 _000_000_000_000_000L, "P");
  thousandSuffixes.put(1 _000_000_000_000_000_000L, "E");
}

public static String formatSuffixes(long value) {
  if (value == Long.MIN_VALUE) return formatSuffixes(Long.MIN_VALUE + 1);
  if (value < 0) return "-" + formatSuffixes(-value);
  if (value < 1000) return Long.toString(value);
  Map.Entry < Long, String > e = thousandSuffixes.floorEntry(value);
  Long divideBy = e.getKey();
  String suffix = e.getValue();
  long truncated = value / (divideBy / 10);
  boolean hasDecimal = truncated < 100 && (truncated / 10 d) != (truncated / 10);
  return hasDecimal ? (truncated / 10 d) + suffix : (truncated / 10) + suffix;
}

and here's the code to get the result from those function above:

String product = productCategory.getProductName();
String number = GeneralUtils.extractNumber(product);
String formattedString = GeneralUtils.formatSuffixes(Long.valueOf(number));
Log.e("numberMatches", "numberMatches: " + number);
Log.e("formattedString", "formattedString: " + formattedString);

How do I join the formatted string with the string before and its after to get a result look like this in Android?

Recharge Data 100K only in your location

Any help will be much appreciated.

Thank you.

Upvotes: 0

Views: 95

Answers (1)

Andy Turner
Andy Turner

Reputation: 140514

Use String.replaceAll to replace occurrences of number with formattedString:

String newProduct = product.replaceAll("\\b" + number + "\\b", formattedString);

Note that number should be surrounded by work breaks (as shown here) to ensure you don't accidentally replace, say, the 1000 and the start of 1000000 and get 1k000.

You can do multiple replacements in a string using a Matcher:

Pattern pattern = Pattern.compile("\\d+");  // Do this once, store in a constant.

Matcher m = pattern.matcher(product);
StringBuffer sb = new StringBuffer();
while (m.find()) {
  String number = m.group();
  String formattedString = GeneralUtils.formatSuffixes(Long.valueOf(number));

  m.appendReplacement(sb, formattedString);
}
m.appendTail(sb);

String newProduct = sb.toString();

Upvotes: 1

Related Questions