Reputation: 4473
I want an array of objects that are distinct by a certain field. The array is already sorted by this field so identifying which fields to remove should follow this: the value of the previous field should be different from current value of the field.
For example, this array
[{A:'1',B:'1'},{A:'2',B:'2'},{A:'2',B:'3'}]
should transform to
[{A:'1',B:'1'},{A:'2',B:'2'}]
I tried the following:
%dw 2.0
output application/json
var payload=[{A:'1',B:'1'},{A:'2',B:'2'},{A:'2',B:'3'}]
---
(payload map (
(a,i) -> ( (a) if payload[i-1].A != $.A )
))
but it does not work. If I do not use the current item ($) then it works like this
(a,i) -> ( (a) if payload[i-1].A != '2' )
But I need the current and previous items to be present to determine that current item is new (not equal for previous one).
Upvotes: 0
Views: 4071
Reputation: 94
I will give a more general answer that will not only distinct by 'A' but also distinct by 'B' because it is not clear in the question wording if doing distinct by only 'A' is enough. Although your dataweave tries to distinct only by 'A', your example has only two equal As and no two equal Bs - which is one specific case. So I will assume that no two As should be equal and no two Bs should be equal.
Some examples with desired outputs:
Example(i): [{A:'1',B:'1'},{A:'2',B:'2'},{A:'3',B:'2'}] -> [{A:'1',B:'1'},{A:'2',B:'2'}]
Example(ii): [{A:'1',B:'1'},{A:'2',B:'2'},{A:'2',B:'2'}] -> [{A:'1',B:'1'},{A:'2',B:'2'}]
Example(iii): [{A:'1',B:'1'},{A:'2',B:'2'},{A:'2',B:'3'}] -> [{A:'1',B:'1'},{A:'2',B:'2'}]
Example(iv): [{"A":'1',"B":'1'},{"A":'2',"B":'2'},{"A":'3',"B":'2'},{"A":'2',"B":'2'}] -> [{A:'1',B:'1'},{A:'2',B:'2'}]
arr distinctBy ($.A + $.B)
. But this would work only in the case of example(ii) because it will distinct by combined A and B. Example(i) and example(iii) will remain unchanged. Example(iv) will transform to [{"A":'1',"B":'1'},{"A":'2',"B":'2'},{"A":'3',"B":'2'}]
. %dw 2.0
output application/json
var arr = [{"A":'1',"B":'1'},{"A":'2',"B":'2'},{"A":'3',"B":'2'}]
---
(arr distinctBy $.A) filter ((arr distinctBy $.B) contains $)
Upvotes: 1
Reputation: 2233
You should be able to ignore the fact that your array is sorted: you don't need the convenience of knowing the current value is distinct from the previous. You can use distinctBy
instead:
%dw 2.0
output application/json
var arr = [{A:'1',B:'1'},{A:'2',B:'2'},{A:'2',B:'3'}]
---
arr distinctBy $.A
Returns
[
{
"A": "1",
"B": "1"
},
{
"A": "2",
"B": "2"
}
]
Here are the docs for distinctBy
if you're interested: https://docs.mulesoft.com/mule-runtime/4.1/dw-core-functions-distinctby
Upvotes: 3