1

I need to compare the field(Doc) in a single array and if their values matched I need to calculate the minimum value of another filed(Number)

Here is an example of the array:

 [
    {

        "Doc": "test1",
        "Number": 91
    },

    {
        "Doc": "test1",
        "Number": 94
    },
        {
        "Doc": "test1",
        "Number": 40
    },
        {
        "Doc": "test2",
        "Number": 82
    },
        {
        "Doc": "test2",
        "Number": 80
    }
]

In the above array, if Doc is same I want to get the minimum value of the Number field. My output should be like this:

[
    {
        
        "Doc": "test1",
        "Number": 40
    }
        {
        "Doc": "test2",
        "Number": 80
    }
]
Zak01
  • 7
  • 3

4 Answers4

2

An alternative using valuesOf:

%dw 2.0
output application/json
fun byDoc() = valuesOf(payload groupBy ((item, index) -> item.Doc)) 
fun minNumber(array : Array) = array minBy ((item) -> item.Number)
---
byDoc() map ((item, index) -> minNumber(item))
afelisatti
  • 2,770
  • 1
  • 13
  • 21
  • Appreciate your help @afelisatti. However, when I tried using your code sample in the dataweave playground, I am getting this error below. I am new to Mule and appreciate your response. Thanks again! Unexpected character '{' at payload@[14:9] (line:column), expected ']', while reading `payload` as Json. 14| { ^ Trace: at main::main (line: 6, column: 1) – Zak01 Jan 25 '22 at 22:39
  • This solution is also working for me. I tested it on the dataweave playground. I didn't know valueOf could also be used here. – Zak01 Jan 25 '22 at 23:27
1

First group by Doc, mapObject() to get the minimum of each group, then pluck() to get the expected output.

%dw 2.0
output application/json
---
payload groupBy ((item, index) -> item.Doc)
    mapObject ((value, key, index) -> (key): min(value.Number) )
    pluck ((value, key, index) -> { Doc: key, Number: value})

Input:

[ 
    {

        "Doc": "STR23756",
        "Number": 91
    },

    {
        "Doc": "STR23756",
        "Number": 94
    },
        {
        "Doc": "STR23756",
        "Number": 40
    },
        {
        "Doc": "STR23757",
        "Number": 82
    },
        {
        "Doc": "STR23757",
        "Number": 80
    }
]

Output:

[
  {
    "Doc": "STR23756",
    "Number": 40
  },
  {
    "Doc": "STR23757",
    "Number": 80
  }
]
aled
  • 21,330
  • 3
  • 27
  • 34
  • Thanks for the response. Could you please show me an example of this. I've tried the solution but it's giving me the following dataweave error: Invalid input 'g', expected Namespace (line 5, column 9): 5| payload groupBy ((item, index) -> item.Doc) ^ Location: main (line: 5, column:9) – Zak01 Jan 25 '22 at 22:18
  • I tested and got the expected output. Not sure what is the problem that you are having. I'll add the output in my answer. – aled Jan 25 '22 at 22:53
  • Are you trying with the new official version of the playground? https://developer.mulesoft.com/learn/dataweave/ – aled Jan 25 '22 at 22:57
  • Its working for me now. Thank you so much for your answer! I do have another scenario where I have two similar arrays and I need to do the same codding i.e look for matching Doc field and get the least value of number. How would we do this similar scenario with two identical arrays? – Zak01 Jan 25 '22 at 23:25
  • You can try to adapt the script to the new structure or ask a new question. – aled Jan 25 '22 at 23:35
  • Sure will do! Thanks @aled – Zak01 Jan 26 '22 at 23:03
  • what if I want to add additional fields in the output from my payload. I do have other fields that are in the same object that I need to capture. Please let me know if you would like me to post another question so I can post the sample payload and output. Thanks – Zak01 Jan 28 '22 at 05:56
  • That would different enough to warrant a different question with its own examples. – aled Jan 28 '22 at 13:04
0

%dw 2.0 output application/json

payload groupBy $.Doc mapObject ((item, key, index) -> (key): min(item.Number) ) pluck ((item, key, index) -> { Doc: key, Number: item})

  • this solution works as long as there is data in these fields. It fails if any of these fields are Null. Is there a way we look for Null value and don't include in this transformation? – Zak01 Jan 29 '22 at 18:13
0

Both of these answers worked for me.

Solution# 1:

%dw 2.0
output application/json
---
payload groupBy ((item, index) -> item.Doc)
    mapObject ((value, key, index) -> (key): min(value.Number) )
    pluck ((value, key, index) -> { Doc: key, Number: value})

Solution# 2:

%dw 2.0
output application/json
fun byDoc() = valuesOf(payload groupBy ((item, index) -> item.Doc)) 
fun minNumber(array : Array) = array minBy ((item) -> item.Number)
---
byDoc() map ((item, index) -> minNumber(item))
Zak01
  • 7
  • 3