I already have this answer for object, but looking a way to improve this to be able to work with array of same object types:
%dw 1.0
%output application/json
%function filterKeys(o, k)
o mapObject
{
($$):
$ when ($ is :string and not (k contains ($$ as :string)))
otherwise orderMembers($, k)
}
orderBy $$
%function splitString(s) s splitBy "," map trim $
%function orderMembers(x, k)
x match {
a is :array -> a orderBy $,
o is :object -> filterKeys(o, k),
s is :string -> orderMembers(splitString(s), k)
when s contains ',' otherwise s,
default -> $
}
%var testData={ccc:"333", ddd: ["555", "333", "222"], bbb: "223,221,222", eee: "456, 789, 123", aaa: 11}
---
orderMembers(testData, ["bbb"])
how to modify it so it can work with that data sample:
%var testData=[{ccc:"333", ddd: ["555", "333", "222"], bbb: "223,221,222", eee: "456, 789, 123", aaa: 11}, {ccc:"333", ddd: ["555", "333", "222"], bbb: "223,221,222", eee: "456, 789, 123", aaa: 11}]
I'll make an educated guess that the orderBy() is throwing an error You cannot compare a value of type ::object.
because it is trying to order an array of objects, instead of strings that was the original intended kind of arrays.
A simple but not full proof solution is to check if the first element of the array is a string before trying to sort it. If not we can assume it is objects and just recursively process them. This can be improved, to check for objects, to check the types of all elements of the array, etc. I'll let that as an exercise to the reader.
The simple solution is to change:
a is :array -> a orderBy $,
by
a is :array -> (a orderBy $)
when (a[0] is :string)
otherwise (a map orderMembers($, k)),
You can improve the when
condition, for example to check that all the elements in the array are of a compatible type. I feel that this would be easier in Mule 4 because DataWeave 2.0 has a lot of useful functions to implement tests for arrays and objects.