0

I am having the below payload

{
    "data": {
        "Final_band": {
            "min": "229573",
            "max": "292184"
        }
    },
    "message": "Engine pricing details fetched successfully"
}

Now I am trying to format the values "min": "229573" and "max": "292184" into something like 2,29,573 and 2,92,184.

The problem is I am trying every solution, but I am not getting the desired result

%dw 2.0
import * from dw::util::Values

var minV = round(payload.data.Final_band.min as Number ) as String {format: "#,##,###"}
var maxV = round(payload.data.Final_band.max as Number) as String {format: "#,##,###"}

output application/json
---
{
 "Final_band": {
            "min": minV,
            "max": maxV
        }
    }

Firstly, I am rounding off the numeric values, and then I coercing the same into string and then applying format: "#,##,###"

but it outputs the "min":"229,573" and "max": "292,184"

it is working fine for format: "#,#####" i,e "min":"2,29573" and "max": "2,92184"

but when I add more comma(,) for thousand place, it won't work as expected

jack
  • 112
  • 1
  • 8
  • The example inputs provided are already integer so rounding them does nothing. Do you mean that other inputs can be floating point too? – aled Oct 21 '22 at 11:56

1 Answers1

1

The formatting of number in Dataweave is based on java.text.DecimalFormat (reference). Which does not support variable width groups. I only see you have two options.

  1. You will either have to use another 3rd party java library that can handle this and use Java module to invoke the required methods.
  2. You can implement your own logic which is fairly easy for this in Dataweave. (Infact if you see in the other java question, most answers have suggested their own implementation)
%dw 2.0
output application/json
/**
 * Strip the last digit of number. If decimal strip the number after decimal along with the last digit of whole number
 * Format the remaining numbers with ##,##. 
 * Append the stripped part to this formatted number. 
 */
fun indianFormatNum(num: Number) = 
    if(num >= 0 and num < 10) num // otherwise this will pad single digit numbers with a 0
    else do {
    //lets say input is 123456.78
    var appendLater = (num mod 10) as String // value will be 6.78
    var remainingNumner = floor(num / 10) // value will be 12345
    ---
    remainingNumner as String {format: "##,##"} ++ appendLater
    // 1,23,45 ++ 6.78
}
---
{
    a: indianFormatNum(12345), // outputs 12,345
    b: indianFormatNum(123457.89), // outputs 1,23,457.89
    c: indianFormatNum(8)
}
Harshank Bansal
  • 2,798
  • 2
  • 7
  • 22
  • thanks Harshank, this is flexible customized version, but I would more likely to prefer the first option. – jack Oct 21 '22 at 13:03
  • I agree. I would have gone with the same. There is a ICU4j which I can find. But it is a 16 MB jar therefore I didn't mention it in the answer. – Harshank Bansal Oct 21 '22 at 14:08
  • Okay, thanks for the information, I have searched a lot for 3rd party but didn't get much option, however, this is the very rare use case in my application, hence I don't think that I should go for 16 mb jar for that, once again thanks so much for the help. – jack Oct 21 '22 at 15:29