Skip to content

recursive search on a nested (multidimensional) collection for groovy

you can search for any object in a nested list containing hash’s and lists recursively, check out the tests for examples:

here are the tests:

class SearchNestedHashTests extends GrailsUnitTestCase {
    protected void setUp() {
        super.setUp()
    }
    protected void tearDown() {
        super.tearDown()
    }
    void testHashMap(){
 
            def map = [
                            'x' , 'y', 's'
                         ]
 
            assertTrue SearchNestedHash.search(map,'x')
 
            def a = 'a'
            def b = false
            def c = 1
 
            map= [
                        [[a,b] : c] : 'y'
                   ]
 
            assertTrue SearchNestedHash.search(map,a)
            assertTrue SearchNestedHash.search(map,b)
            assertTrue SearchNestedHash.search(map,c)
            assertTrue SearchNestedHash.search(map,false)
 
            map = [
                           'y' : 'null'
                       ]
 
            assertFalse SearchNestedHash.search(map,'x')
 
            map = [
                           'x':'null'
                       ]
 
            assertTrue SearchNestedHash.search(map,'x')
 
            map = [
                        ['n' : 'y'] : 'x'
                    ]
 
            assertFalse SearchNestedHash.search(map,'t')
            assertFalse SearchNestedHash.search(map,null)
            assertTrue SearchNestedHash.search(map,'x')
 
            map= [
                        ['n' : 'x'] : 'y'
                    ]
 
            assertTrue SearchNestedHash.search(map,'x')
 
            map = [
                        ['x' : 'n'] : 'y'
                    ]
 
            assertTrue SearchNestedHash.search(map,'x')
 
            map= [
                        [['x':'z'] : 'n'] : 'y'
                    ]
 
            assertTrue SearchNestedHash.search(map,'x')
 
            map= [
                        [['c':'x'] : 'n'] : null
                    ]
 
            assertTrue SearchNestedHash.search(map,'x')
 
            def x = ['a':'b']
 
            map= [
                        [['y': x ] : null] : 'y'
                    ]
 
            assertTrue SearchNestedHash.search(map,x)
 
            map= [
                        [['y': ['a':'b'] ] : null] : 'y'
                    ]
 
            assertTrue SearchNestedHash.search(map,x)
 
            map= [
                        [['s':'x'] : null] : 'y'
                    ]
 
            assertTrue SearchNestedHash.search(map,'x')
 
            def crazyMap = [
                        [['c':'v'] : [['c':[['c':[[[[['xxsxx':'v'] : [['c':[['c':[[[          'X'            :'v']:'v']:'v']]:'v']]:'v']]:'v']:'v']:'v']]:'v']]:'v']] : 'y'
                    ]
 
            assertFalse SearchNestedHash.search(crazyMap,'q')
            assertFalse SearchNestedHash.search(crazyMap,'x')//only the capital X is inside
            assertTrue  SearchNestedHash.search(crazyMap,'X')//only the capital X is inside
            assertTrue  SearchNestedHash.search(crazyMap,['xxsxx':'v'])
 
     }
}

here is the Class:

class SearchNestedHash {
    static def found = false;
 
    static synchronized search(collection,targetObj){
        found = false;
        return searchRec(collection,targetObj)
    }
 
    static synchronized searchRec(collection, targetObj){
 
        if(collection instanceof List && collection.contains(targetObj))
            return true
 
        collection.each({
 
                if(
                    (
                        collection instanceof Map
                        &&
                        (
                            it.key == targetObj ||
                            it.value == targetObj ||
                            it.key    instanceof List && it.key    .contains(targetObj) ||
                            it.value instanceof List && it.value .contains(targetObj)
                        )
                    )
                        ||
                    (
                        it instanceof List && it == targetObj
                    )
 
                ){found = true;return}
            })
 
        if(!found){
 
            collection.each({
 
                    if(it.key instanceof Map)
                    searchRec(it.key,targetObj)
 
                    if(it.value instanceof Map)
                    searchRec(it.value,targetObj)
 
                    if(it instanceof List)
                    searchRec(it,targetObj)
 
                })
 
        }
        return found
    }
 
}

Categories: Uncategorized, algorithms.

Tags: , , , , , , , , , ,

Comment Feed

No Responses (yet)



Some HTML is OK

or, reply to this post via trackback.