如何使用 DW v1.0 迭代数组和对象

How to iterate array with objects with DW v1.0

我已经有了这个对象的答案,但正在寻找一种方法来改进它以便能够使用相同对象类型的数组:

%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"]) 

如何修改它以便它可以使用该数据样本:

%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}]

我有根据地猜测 orderBy() 正在抛出错误 You cannot compare a value of type ::object. 因为它试图对对象数组进行排序,而不是最初预期的数组类型的字符串。

一个简单但不完整的解决方案是在尝试对数组进行排序之前检查数组的第一个元素是否为字符串。如果不是,我们可以假设它是对象并递归地处理它们。这可以改进,检查对象,检查数组所有元素的类型等。我将把它作为 reader.

的练习

简单的解决方法是更改​​:

     a is :array -> a orderBy $,

来自

     a is :array -> (a orderBy $) 
           when (a[0] is :string) 
           otherwise (a map orderMembers($, k)),

您可以改进 when 条件,例如检查数组中的所有元素是否都是兼容类型。我觉得这在 Mule 4 中会更容易,因为 DataWeave 2.0 有很多有用的函数来实现数组和对象的测试。