3

This is an update to my previous question Find and update in nested json object

Sample Data

TestObj = {
    "Categories": [{
        "Products": [{
            "id": "a01",
            "name": "Pine",
            "description": "Short description of pine."
        },
        {
            "id": "a02",
            "name": "Pine",
            "description": "Short description of pine."
        },
        {
            "id": "a03",
            "name": "Poplar",
            "description": "Short description of poplar."
        }],
        "id": "A",
        "title": "Cheap",
        "description": "Short description of category A."
    },
    {
        "Product": [{
            "id": "b01",
            "name": "Maple",
            "description": "Short description of maple."
        },
        {
            "id": "b02",
            "name": "Oak",
            "description": "Short description of oak."
        },
        {
            "id": "b03",
            "name": "Bamboo",
            "description": "Short description of bamboo."
        }],
        "id": "B",
        "title": "Moderate",
        "description": "Short description of category B."
    }]
};

My Function

function getObjects(obj, key, val, newVal) {
    var newValue = newVal;
    var objects = [];
    for (var i in obj) {
        if (!obj.hasOwnProperty(i)) continue;
        if (typeof obj[i] == 'object') {
            objects = objects.concat(getObjects(obj[i], key, val, newValue));
        } else if (i == key && obj[key] == val) {
            obj[key] = newValue;
        }
    }
    return obj;
}

called as

getObjects(TestObj, 'id', 'A', 'B');

It works fine if I'm going to update id; since id don't have duplicates. But if I'm updating name all data matching key value pair is updated. But how to constrain it into a particular key-pair value.

What shall i provide to the function to constrain the update scope and how to implement it. Please help me.

Note: The json that I will b manipulating will be dynamically generated so I can't have any hard coded value in the function

Community
  • 1
  • 1
Okky
  • 10,338
  • 15
  • 75
  • 122
  • 1
    Make values unique or break the loop once you found one (or a defined amount) – Virus721 Aug 01 '13 at 12:06
  • The values are dynamically generated so I can't, assure that it will be unique. Also I can't break the loop since I may have key-pair value in 1st child but have to update in 2nd child – Okky Aug 01 '13 at 12:11
  • 2
    How do you know which child should be updated? I mean, if you rely on key and value only, you have to update all matching pairs, but if you want to update just one of them then there should be an additional constraint. For example if the constraint is `id`, then it should be really easy to implement. – pckill Aug 07 '13 at 14:05
  • You can check whether input source from where you get data to update json is providing some other constraint on basis of which we can make different combination to update json. – Mithlesh Kumar Aug 07 '13 at 14:30
  • I'm not sure I get the point of this function. What is your use case ? – LeGEC Aug 07 '13 at 16:13
  • I did this by passing the whole path that is dynamically generated http://stackoverflow.com/questions/18098594/jquery-set-value-for-the-json-path-provided-as-string – Okky Aug 08 '13 at 04:51

1 Answers1

7

I think you can somehow use a path to locate the value and then do the update. I got the idea from this post. (answered by @shesek)

var getPath = function (obj, path, newValue) {
    var parts = path.split('.');
    while (parts.length > 1 && (obj = obj[parts.shift()]));
    obj[parts.shift()] = newValue;
    return obj;
}

console.log(getPath(TestObj, 'Categories.0.Products.1.id', 'AAA'))
console.log(TestObj)

So you can pass in the path to the object, for example, if you want to update the id of the following object to "AAA", you can pass in Categories.0.Products.1.id

    {
        "id": "a02",
        "name": "Pine",
        "description": "Short description of pine."
    }

then, the object will become

    {
        "id": "AAA",
        "name": "Pine",
        "description": "Short description of pine."
    }

Hope it can shed some light on!

Community
  • 1
  • 1
zs2020
  • 53,766
  • 29
  • 154
  • 219