0

The Problem

The method to search through a JSOn Object that I found in this SO answer works well, however, I need it to return the "object that contains the matched object, value or pair" rather than the matched object itself.

The Code

function getObjects(obj, key, val) {
    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));
        } else if (i == key && obj[key] == val) {
            objects.push(obj);
        }
    }
    return objects;
}
getObjects(obj, key, val);

The Question

How can I augment that to return the object that contains the matched object/value/pair instead of just the match itself? (jQuery or JS)

JSON Sample

For example, I need to check if the value "Delivered, Front Door/Porch" of key Event (or Event[#text]) exists, and if so, I need to find the EventDate in that object in which the Event was found.

{
    "TrackResponse": {
        "TrackInfo": {
            "@attributes": {
                "ID": "9470111699000308312927"
            },
                "GuaranteedDeliveryDate": {
                "#text": "September 9, 2015"
            },
                "TrackSummary": {
                "EventTime": {
                    "#text": "2:06 pm"
                },
                    "EventDate": {
                    "#text": "September 10, 2015"
                },
                    "Event": {
                    "#text": "Delivered, Front Door/Porch"
                },
                ...
            },
                "TrackDetail": [{
                "EventTime": {
                    "#text": "8:07 am"
                },
                ...
            }, ... {
                "EventTime": {},
                ...
            }]
        }
    }
}
Community
  • 1
  • 1
Andre Bulatov
  • 1,090
  • 3
  • 16
  • 47
  • Perhaps you need to look at it from a different angle. You say "the object that contains the match," but in reality, that object *is* the match. Make sense? – keeehlan Sep 15 '15 at 22:31
  • Thank you, I am looking into that. I am also looking through the answer which was provided as "Duplicate link," and as that answer is pretty long, it's gonna take me a little while to consume and try. If my question really is duplicate, I will delete it. – Andre Bulatov Sep 15 '15 at 22:47
  • If you feel the linked material does not solve your problem, please let me know and I will remove the duplicate selection. – Travis J Sep 15 '15 at 22:48
  • @TravisJ, thank you! Apologies if it IS in fact a duplicate, I searched through literally over a dozen similar sounding questions to no avail (though perhaps it's just my ignorance showing). *I'll be back.* – Andre Bulatov Sep 15 '15 at 22:50
  • 1
    Nah, it can be hard to find the exact name of the thing you are looking for sometimes. There is nothing wrong with having a "signpost" question which just makes linking more viable. I was just trying to help you solve your problem without reproducing material. But if it does not help, I can reopen it. – Travis J Sep 15 '15 at 22:53
  • 1
    Yeah, posts like these still come up in searches and make it even easier to find the community-accepted answer. Nothing to worry about. – keeehlan Sep 15 '15 at 22:59
  • 1
    @AndreBulatov - So for your exact situation, are you only looking for the one date? For example, the linked material could be used like this: https://jsfiddle.net/vnxfujgv/ – Travis J Sep 15 '15 at 23:06
  • @TravisJ Thank you for the awesome code -- helped me further understand my problem. The JSON USPS returns to me has an object I need to search (*here your code works perfect, for TrackSummary obj*), but if the query is not matched, I then need to search the array of objects, `TrackDetail`. I only need this function for this JSON and I basically need to find the corresponding EventDate of the matched object of objects. I've tried to adapt your code into a "Full Search" here: https://jsfiddle.net/iamandrebulatov/fx0Lsbn0/4/ but I can't make it work. – Andre Bulatov Sep 16 '15 at 04:25

1 Answers1

0

Finally got this working with the following function:

function ContainsKeyValue(obj, key, value) {
    if (obj[key] === value) return true;
    for (all in obj) {
        if (obj[all] != null && obj[all][key] === value) {
            return true;
        }
        if (typeof obj[all] == "object" && obj[all] != null) {
            var found = ContainsKeyValue(obj[all], key, value);
            if (found == true) return true;
        }
    }
    return false;
}
for (var eventType in historyDates) {
    for (var i = 0; i < trackingDetails.length; i++) {
        var detail = trackingDetails[i];
        if (ContainsKeyValue(detail, "#text", eventType)) {
            historyDates[eventType] = detail.EventDate["#text"];
        }
    }
}
Andre Bulatov
  • 1,090
  • 3
  • 16
  • 47