2016-09-23 61 views
0

我有一個複雜的結構,它嵌套如下所示。我試圖通過它的兄弟鍵:值對來訪問嵌套鍵的值。在嵌套映射中使用其兄弟鍵值對訪問子節點

如:我複雜的結構是:

{ 

    key1:value, 

    key2: 

     [ 

     {a:1,c:{d:1}}, 

     {a:2,c:{d:0}}, 

     {a:3,c:{d:1}} 

     ] 

    } 

我試圖返回d的值,其中一個:3。很明顯,d是一個兄弟姐妹的孩子。如果我遍歷key2並得到c的值,我可以在c的孩子上做一個DFS來找到所需的值。

如果我指定兄弟關鍵字:值對作爲嵌套的一個級別,這不會有幫助。它需要一個像遍歷的XPath。對於上述情況說,我的表達將是:

(a:1>>c)->{d:1} 
(a:2>>c::d)->0 
(key2::a)->[1,2,3] 

其中::是兒童符號和>>是兄弟符號。 有沒有一種簡單或優雅的方法來解決這個問題? java有沒有類似this的庫來解決這個問題?

+1

嘗試:https://mvnrepository.com/artifact/com.jayway.jsonpath/json-path/2.2.0(https://github.com/jayway/JsonPath)很容易指定到JSON對象的路徑。 – AlexC

回答

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的來源,文檔和示例。