Sven,

Are your values Strings or numbers? Meaning does the JSON look like:

{ "a": "2.1234567891E10" }
 or
{ "a" : 2.1234567891E10 }

If the latter, would the output field ("a" or "new_a" or whatever)
have to remain a number, or is a String ok?  I think most
applications/libraries will default the "printed" version of a number
to Java's Number.toString() method, so if you wanted any number to be
displayed with the thousands separator, then you really are doing
string manipulation vs math, so what you propose should work fine.
Adding a thousands separator is itself a string operation as there is
no real concept of a separator when it comes to dealing with numbers
as numbers.

If you just want to change the "manageable" numbers to human readable
format (and have them remain Numbers), you could use ExecuteScript
with Groovy and just read in and write out the JSON object, Groovy
will represent some of the example values in their more human-readable
form.  For example, I started with this JSON:

{
  "a": 10000,
  "b": 2.23456789E6,
  "c": 2.1234567891E10,
  "d": 15.123456789E7,
  "e": 2.1234567891E23
}


And used this Groovy script in ExecuteScript:

import groovy.json.*
import org.apache.commons.io.IOUtils
import java.nio.charset.StandardCharsets

def flowFile = session.get()
if(!flowFile) return
flowFile = session.write(flowFile, { inputStream, outputStream ->
   def json = new
JsonSlurper().parseText(IOUtils.toString(inputStream,
StandardCharsets.UTF_8))
   
outputStream.write(JsonOutput.prettyPrint(JsonOutput.toJson(json)).getBytes(StandardCharsets.UTF_8))
} as StreamCallback)
session.transfer(flowFile, REL_SUCCESS)


And got this result:
{
    "a": 10000,
    "b": 2234567.89,
    "c": 21234567891,
    "d": 151234567.89,
    "e": 2.1234567891E+23
}

Your original example values ("a" through "d") have been "expanded",
where the one I added ("e", with a large exponent) has remained in
scientific notation.

Alternatively, if you have a flat JSON object and don't mind that the
numeric values will be replaced by strings, you can add the following
to the script before the outputStream.write() line:

json.each {k,v ->
  json[k] = java.text.NumberFormat.getNumberInstance(Locale.US).format(v)
}


to get this output:
{
    "a": "10,000",
    "b": "2,234,567.89",
    "c": "21,234,567,891",
    "d": "151,234,567.89",
    "e": "212,345,678,910,000,000,000,000"
}

If your JSON is not flat but you know which fields contain the numbers
you wish to transform, you can refer to those fields in dot notation
(vs doing the json.each() to get each top-level key/value pair) as
they are just Maps once the JSON has been "slurped" [1].

Regards,
Matt

[1] http://groovy-lang.org/json.html

On Thu, Jan 26, 2017 at 9:41 AM, Sven Davison <[email protected]> wrote:
> I have a json object the SOMETIMES contains a scientific notation for the
> value. I want to have a nice or "human readable" number w/ thousands
> separator.
>
> example values:
> 10000
> 2.23456789E6
> 2.1234567891E10
> 15.123456789E7
>
> what i thought of doing was checking for the existance of E. then forking it
> in the flow. if it has an E.. get the value to the right of the E. split the
> string into an array (including the .). finding the index location of the
> "." then moving it X positions per value indicated on the right of the E.
> once thats done, go back and add the thousands seperator "," for easy
> reading.
>
> this is string manipulation rather than "math".. Can anyone recomend an
> easier way?
>
>

Reply via email to