2016-10-11 4 views
0

Мне нужно реализовать метод, который будет сканировать строку JSON для определенного targetField и либо вернуть значение этого поля (если оно существует), либо null (если это не так) :Рекурсивно извлекать значения полей JSON в Groovy

// Ex: extractFieldValue(/{ "fizz" : "buzz" }/, 'fizz') => 'buzz' 
// Ex: extractFieldValue(/{ "fizz" : "buzz" }/, 'foo') => null 
String extractFieldValue(String json, String targetField) { 
    // ... 
} 

Это решение должно быть рекурсивной и работать на любом вложенности уровне в иерархической() JSON строки. Также он должен работать и для массивов JSON.

Моя лучшая попытка до сих пор:

String extractFieldValue(String json, String targetField) { 
    def slurper = new JsonSlurper() 
    def jsonMap = slurper.parseText(json) 

    jsonMap."${targetField}" 
} 

Это работает только на верхнем уровне (не вложенных) в формате JSON полей. Я попросил Google Gods использовать рекурсивно JsonSlurper, но не нашел ничего полезного. Есть идеи?

+1

что если множественность матч? –

+2

Довольно точно, когда вы наклеили JSON на карту, вы можете использовать что-то вроде http://stackoverflow.com/questions/6185746/groovy-map-find-recursive –

+0

Good point @tim_yates - я был бы доволен взяв первое найденное значение. – smeeb

ответ

2

Учитывая эту строку ввода в переменную с именем json:

{ 
    "a":"a", 
    "b":{"f":"f", "g":"g"}, 
    "c":"c", 
    "d":"d", 
    "e":[{"h":"h"}, {"i":{"j":"j"}}], 
} 

Этот сценарий:

import groovy.json.JsonSlurper 

def mapOrCollection (def it) { 
    it instanceof Map || it instanceof Collection 
} 

def findDeep(def tree, String key) { 
    switch (tree) { 
     case Map: return tree.findResult { k, v -> 
      mapOrCollection(v) 
       ? findDeep(v, key) 
       : k == key 
        ? v 
        : null 
     } 
     case Collection: return tree.findResult { e -> 
      mapOrCollection(e) 
       ? findDeep(e, key) 
       : null 
     } 
     default: return null 
    } 
} 

('a'..'k').each { key -> 
    def found = findDeep(new JsonSlurper().parseText(json), key) 
    println "${key}: ${found}" 
} 

дает следующие результаты:

a: a 
b: null 
c: c 
d: d 
e: null 
f: f 
g: g 
h: h 
i: null 
j: j 
k: null 
Смежные вопросы