I am trying to create a complex object based on metadata I have. It is an array of attributes which I am iterating and trying to create a dict. For example below is the array:
[
    "itemUniqueId",
    "itemDescription",
    "manufacturerInfo[0].manufacturer.value",
    "manufacturerInfo[0].manufacturerPartNumber",
    "attributes.noun.value",
    "attributes.modifier.value",
    "attributes.entityAttributes[0].attributeName",
    "attributes.entityAttributes[0].attributeValue",
    "attributes.entityAttributes[0].attributeUOM",
    "attributes.entityAttributes[1].attributeName",
    "attributes.entityAttributes[1].attributeValue",
    "attributes.entityAttributes[1].attributeUOM",
]
This array should give an output as below:
{
    "itemUniqueId": "",
    "itemDescription": "",
    "manufacturerInfo": [
        {
            "manufacturer": {
                "value": ""
            },
            "manufacturerPartNumber": ""
        }
    ],
    "attributes": {
        "noun": {
            "value": ""
        },
        "modifier": {
            "value": ""
        },
        "entityAttributes": [
             {
                 "attributeName": "",
                 "attributeValue": "",
                 "attributeUOM": ""
             },
             {
                "attributeName": "",
                "attributeValue": "",
                "attributeUOM": ""
             }
        ]
    }
}
I have written this logic but unable to get the desired output. It should work on both object and array given the metadata.
source_json = [
    "itemUniqueId",
    "itemDescription",
    "manufacturerInfo[0].manufacturer.value",
    "manufacturerInfo[0].manufacturerPartNumber",
    "attributes.noun.value",
    "attributes.modifier.value",
    "attributes.entityAttributes[0].attributeName",
    "attributes.entityAttributes[0].attributeValue",
    "attributes.entityAttributes[0].attributeUOM",
    "attributes.entityAttributes[1].attributeName",
    "attributes.entityAttributes[1].attributeValue",
    "attributes.entityAttributes[1].attributeUOM",
]
for row in source_json:
    propertyNames = row.split('.')
    temp = ''
    parent = {}
    parentArr = []
    parentObj = {}
    # if len(propertyNames) > 1:
    arrLength = len(propertyNames)
    for i, (current) in enumerate(zip(propertyNames)):
        if i == 0:
            if '[' in current:
                parent[current]=parentArr
            else:
                parent[current] = parentObj
            temp = current
        if i > 0 and i < arrLength - 1:
            if '[' in current:
                parent[current] = parentArr
            else:
                parent[current] = parentObj
            temp = current
        if i == arrLength - 1:
            if '[' in current:
                parent[current] = parentArr
            else:
                parent[current] = parentObj
            temp = current
            # temp[prev][current] = ""
    # finalMapping[target] = target
print(parent)
                There's a similar question at Convert Dot notation string into nested Python object with Dictionaries and arrays where the accepted answer works for this question, but has unused code paths (e.g. isInArray) and caters to unconventional conversions expected by that question:
"arrOne[0]": "1,2,3" → "arrOne": ["1", "2", "3"] instead of"arrOne[0]": "1,2,3" → "arrOne": ["1,2,3"] or"arrOne[0]": "1", "arrOne[1]": "2", "arrOne[2]": "3" → "arrOne": ["1", "2", "3"]Here's a refined implementation of the branch function:
def branch(tree, path, value):
    key = path[0]
    array_index_match = re.search(r'\[([0-9]+)\]', key)
    if array_index_match:
        # Get the array index, and remove the match from the key
        array_index = int(array_index_match[0].replace('[', '').replace(']', ''))
        key = key.replace(array_index_match[0], '')
        # Prepare the array at the key
        if key not in tree:
            tree[key] = []
        # Prepare the object at the array index
        if array_index == len(tree[key]):
            tree[key].append({})
        # Replace the object at the array index
        tree[key][array_index] = value if len(path) == 1 else branch(tree[key][array_index], path[1:], value)
    else:
        # Prepare the object at the key
        if key not in tree:
            tree[key] = {}
        # Replace the object at the key
        tree[key] = value if len(path) == 1 else branch(tree[key], path[1:], value)
    return tree
Usage:
VALUE = ''
def create_dict(attributes):
    d = {}
    for path_str in attributes:
        branch(d, path_str.split('.'), VALUE)
    return d
source_json = [
    "itemUniqueId",
    "itemDescription",
    "manufacturerInfo[0].manufacturer.value",
    "manufacturerInfo[0].manufacturerPartNumber",
    "attributes.noun.value",
    "attributes.modifier.value",
    "attributes.entityAttributes[0].attributeName",
    "attributes.entityAttributes[0].attributeValue",
    "attributes.entityAttributes[0].attributeUOM",
    "attributes.entityAttributes[1].attributeName",
    "attributes.entityAttributes[1].attributeValue",
    "attributes.entityAttributes[1].attributeUOM",
]
assert create_dict(source_json) == {
    "itemUniqueId": "",
    "itemDescription": "",
    "manufacturerInfo": [
        {
            "manufacturer": {
                "value": ""
            },
            "manufacturerPartNumber": ""
        }
    ],
    "attributes": {
        "noun": {
            "value": ""
        },
        "modifier": {
            "value": ""
        },
        "entityAttributes": [
             {
                "attributeName": "",
                "attributeValue": "",
                "attributeUOM": ""
            },
           {
                "attributeName": "",
                "attributeValue": "",
                "attributeUOM": ""
            }
        ]
    }
}
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With