dataweave

can't get new value of previously updated element in a loop


I have an array of objects.

     [
      {
        "b": 0,
        "a": 5
      },
      {
        "b": 0,
        "a": 10
      },
      {
        "b": 0,
        "a": 15
      }
    ]

Now I want to change every b field to sum of previous object's a and b values.

When I use map function I skip first element because there is no element before it, then I do some calculation on every element. For example on this element: {"a":10,"b":0}, b will be updated to 5 (because in previous object a is 5 and b is 0. So sum is 5). Next, for the 3rd object (which is: {"a":15,"b":0}), b should be updated to 15. Because in the previous iteration, I have updated the value of b to 5.

My problem is DataWeave map function is taking the old value of b instead of updated one. So it's producing below output:

    [
      {
        "b": 0,
        "a": 5
      },
      {
        "b": 5,
        "a": 10
      },
      {
        "b": 10,
        "a": 15
      }
    ]

Instead I'm expecting this output:

    [
      {
        "b": 0,
        "a": 5
      },
      {
        "b": 5,
        "a": 10
      },
      {
        "b": 15,
        "a": 15
      }
    ]

Here is my script:

    %dw 2.0
    output application/json
    ---
    payload map ((item, index) -> {
        b: if (index == 0) 0 else (payload[index - 1].a + payload[index - 1].b),
        a: item.a
    })

I don't know how to get the updated value in every iteration. Any help would be appreciated.


Solution

  • Try the below solution

    Input

    [
      {
        "b": 0,
        "a": 5
      },
      {
        "b": 0,
        "a": 10
      },
      {
        "b": 0,
        "a": 15
      }
    ]
    

    Dataweave Script

    %dw 2.0
    output application/json
    ---
    (payload reduce ((item, acc={b: 0, arr: []}) -> {
        b: if (isEmpty(acc.arr)) 0 else acc.b + acc.arr[-1].a,
        a: item.a,
        arr: acc.arr ++ [{ b: if (isEmpty(acc.arr)) 0 else acc.b + acc.arr[-1].a, a: item.a }]
    })).arr
    

    Output

    [
      {
        "b": 0,
        "a": 5
      },
      {
        "b": 5,
        "a": 10
      },
      {
        "b": 15,
        "a": 15
      }
    ]