我有一个嵌套的复杂结构,如下所示。我试图用它的兄弟键:值对来访问嵌套键的值。
例如:我的复杂结构是:
{
key1:value,
key2:
[
{a:1,c:{d:1}},
{a:2,c:{d:0}},
{a:3,c:{d:1}}
]
}
我试图返回d的值,其中a:3。很明显,d是兄弟姐妹的孩子。如果我遍历key2并得到c的值,我可以在c的子节点上做一个DFS来找到所需的值。
如果我指定一个兄弟键:值对作为一个嵌套级别,这将无济于事。它需要像遍历一样的XPath。对于上述情况,我的表达式是:
(a:1>>c)->{d:1}
(a:2>>c::d)->0
(key2::a)->[1,2,3]
where ::是儿童表示法,>>是一个兄弟符号。 是否有简单或优雅的方式来接近这个?是否有像this这样的库来解决这个问题?
答案 0 :(得分:1)
您可以使用Java 8库Dynamics解决这些问题。它允许您以直接但流畅的方式遍历嵌套结构。无效的方式。
Map nestedStructure = ...
// {key1=value, key2=[{a=1, c={d=1}}, {a=2, c={d=0}}, {a=3, c={d=1}}]}
Dynamic data = Dynamic.from(nestedStructure);
// "(a:1>>c)": all "c" values that have sibling "a" = 1
List<Map> aIs1CValues = data.allChildren()
// filter to elements that have an 'a=3' child & a "c" map child
.filter(el -> el.get("a").maybe().as(Integer.class).orElse(0) == 1)
.filter(el -> el.get("c").isMap())
.map(el -> el.get("c").asMap())
.collect(toList()); // [{d=1}]
// "(a:2>>c::d)": all "d" values, with parent key "c" that has sibling "a" = 2
List<Integer> aIs2DValues = data.allChildren()
.filter(el -> el.get("a").maybe().as(Integer.class).orElse(0) == 2)
.filter(el -> el.dget("c.d").is(Integer.class))
.map(el -> el.dget("c.d").as(Integer.class))
.collect(toList()); // [0]
// "(key2::a)": all "a" values, with some parent key "key2"
List<Integer> key2As = data.allChildren()
.filter(el -> el.key().asObject().equals("key2"))
.flatMap(Dynamic::children)
.filter(key2Map -> key2Map.get("a").is(Integer.class))
.map(key2Map -> key2Map.get("a").as(Integer.class))
.collect(toList()); // [1, 2, 3]
我不能完全确定您的真实问题与您的示例相比,如果我们对数据有更多了解,这种处理可能会更简单。例如,如果我们知道 key2 是最高级别且 a 始终存在且是整数,则最后一个问题会更容易。
data.get("key2").children()
.map(child -> child.get("a").as(Integer.class))
.collect(toList()); // [1, 2, 3]
有关来源,文档和示例,请参阅https://github.com/alexheretic/dynamics。