Search code examples
recursiongroovydata-cleaninglinkedhashmap

Remove null values from complex data structure in Groovy or Java


I need to remove the null key values from a complex LinkedHashMap:

Here's a simple Example:
  • Input
[f1:abc, f2:xyz, f3:lmn, test:null, people:[[name:James, City:Atlanta], [name:Rachel, City:null]], person:[name:James, Phone:4045555555, test:null]]
  • Desired Output:
[f1:abc, f2:xyz, f3:lmn, people:[[name:James, City:Atlanta], [name:Rachel]], person:[name:James, Phone:4045555555]]

I'm already half way there, I'm just stuck on removing the nulls from the List (people). Here's what I have so far:

def removeNullValues(Object map) {
    map.collectEntries { k, v -> [k, v instanceof Map? removeNullValues(v) : v]}
            .findAll { k, v -> v != null}
}

Solution

  • You can use polymorphism to select a different method depending on whether the item is a list, map, or other:

    def input = [
       f1:'abc',
       f2:'xyz',
       f3:'lmn',
       test:null,
       woo:[1, 2, null, 3],
       people:[
          [name:'James', City:'Atlanta'],
          [name:'Rachel', City:null]
       ],
       person:[name:'James', Phone:'4045555555', test:null]
    ]
    
    def removeNulls(other) {
        other
    }
    
    def removeNulls(List list) {
        list.findResults { removeNulls(it) }
    }
    
    def removeNulls(Map map) {
        map.findAll { k, v -> v != null }.collectEntries { k, v ->
             [k, removeNulls(v)]
        }
    }
    
    println removeNulls(input)
    

    Which will print:

    [f1:abc, f2:xyz, f3:lmn, woo:[1, 2, 3], people:[[name:James, City:Atlanta], [name:Rachel]], person:[name:James, Phone:4045555555]]