Skip to content
Snippets Groups Projects
flatten_utils.py 3.01 KiB
def flatten_json(y):

    out = dict()

    def flatten(x, name=''):
        if type(x) is dict:
            for a in x:
                flatten(x[a], name + a + '.')
        elif type(x) is list:
            i = 0
            for a in x:
                flatten(a, name + str(i) + '.')
                i += 1
        else:
            out[name[:-1]] = x

    flatten( y )
    return out


def is_cardinal( x ):

    try:
        i = int(x)
        return True
    except:
        return False


def cardinal_key_to_list(x):

    if type(x) is not dict:
        return x

    elif type(x) is dict and all( [is_cardinal(y) for y in x.keys() ] ):

        return [cardinal_key_to_list(v) for v in x.values()]

    elif type(x) is dict:

        return {k: cardinal_key_to_list(v) for k, v in x.items()}


def unflatten_json(y):

    output = dict()

    for key, value in y.items():
        parts = key.split(".")

        d = output

        for j, part in enumerate(parts[:-1]):  # parts[:-1] = all terms but last


            if part not in d:
                d[part] = dict()

            d = d[part]

        d[parts[-1]] = value

    return cardinal_key_to_list(output)



if __name__ == '__main__':

    from pprint import pprint
    import json


    in1 = {"responsibleParty": [
            {
              "email": "data@grandlyon.com",
              "role": "custodian",
              "address": "20 rue du Lac, CS 33569, Lyon cedex 03, 69505, France",
              "individualName": "Géomatique et données métropolitaines",
              "logo": "https://download.data.grandlyon.com/catalogue/images/harvesting/GrandLyon.gif",
              "appliesTo": ["resource1", "resource2"],
              "organisationName": "Metropole de Lyon / Direction Innovation Numérique et Systèmes d'Information (DINSI)"
            },
            {
              "email": "data@grandlyon.com",
              "role": "custodian",
              "address": "une autre adresse",
              "individualName": "Géomatique et données métropolitaines",
              "logo": "https://download.data.grandlyon.com/catalogue/images/harvesting/GrandLyon.gif",
              "appliesTo": "metadata",
              "organisationName": "Metropole de Lyon / Direction Innovation Numérique et Systèmes d'Information (DINSI)"
            }
          ]}

    #in1 = dict(in1)



    flattened_json = flatten_json(in1)
    unflattened_json = unflatten_json(flattened_json)

    print('ORIGINAL')
    pprint(in1)

    print('')


    print('FLATTENED')
    pprint(flattened_json)

    print('')

    print('UNFLATTENED')
    pprint(unflattened_json)

    assert json.dumps(in1, sort_keys=True) == json.dumps(unflatten_json(flatten_json(in1)), sort_keys=True)
    exit(0)


    print(' ')
    with open('flatten_original.json', 'w') as fp:
        json.dump(in1, fp, sort_keys=True)

    with open('flatten_processed.json', 'w') as fp:
        json.dump(unflatten_json(flatten_json(in1)), fp, sort_keys=True)

    print(' ')

    pprint(json.dumps(unflatten_json(flatten_json(in1)), sort_keys=True))