Mona Coder
Mona Coder

Reputation: 6316

Querying JSON array in JSON object value

Using jsonSelect Plugin I am trying to do a query select as below. I am presenting this example.

How can I retrieve the All Project and Contractors who has the Projects in "North" ProjectArea? I already tried this to get the contractor's name but it didn't work

var contractors = [{
    "contractor1": [{
                     "project": "Project 2",
                     "projectArea": "South"
                    },
                    {
                     "project": "Project 101",
                     "projectArea": "East"
                    }],
     "contractor2": [{
                     "project": "Project 500",
                     "projectArea": "North"
                     },  
                     {
                     "project": "Projetc 108",
                     "projectArea": "West"
                    }]
}]

var stringSelect = 'has(:root > .projectArea:val("North"))';
JSONSelect.forEach(stringSelect, contractors, function (resultObj) {
    $('body').append('<p>' + resultObj + '</p>');
});

Upvotes: 1

Views: 86

Answers (1)

76484
76484

Reputation: 8993

I think the only way you are going to be able to achieve what you want is by changing your JSON data structure. Specifically, you have your contractors' names as keys ('contractor1', contractor2'), but they really should be values. The library you are using returns a set of objects, but I don't see any way to step back a level and obtain each object's corresponding key. I suggest structuring your data like this:

var contractors = [
    {
        "name": "contractor1",
        "projects": [
            { "project": "Project 2", "projectArea": "South" },
            { "project": "Project 101", "projectArea": "North" }
        ]
    },
    {
        "name": "contractor2", 
        "projects": [
            { "project": "Project 500", "projectArea": "North" },
            { "project": "Project 108", "projectArea": "West" }
         ]
    }
];

Also, I think you will have to apply two levels of filters, first to get the contractors, and secondly to get each contractor's projects:

JSONSelect.forEach('object:has(.projects:has(.projectArea:val("North")))', contractors, function (contractor) {
    $('body').append('<p>' + contractor.name + '</p>');
    JSONSelect.forEach('object:has(.projectArea:val("North"))', contractor.projects, function (project) {
        $('body').append('<p>' + project.project + '</p>'); 
    });
});

I do not know of any other plugins that do this. If I were to come across this problem, my first inclination would be to solve it using jQuery's $.map and $.grep methods:

var filtered = $.map(contractors, function (contractor) {
    var filteredProjects = $.grep(contractor.projects, function (project) {
        return project['projectArea'] === 'North';
    });
    if (filteredProjects.length) {
        return { 
            'name': contractor.name, 
            'projects': filteredProjects
        };
    }
});

I am using $.grep to filter each contractor's projects to only those with ['projectArea'] === 'North'. If the contractor has any projects that match the filter, a new object with the contractor's name and the filtered projects gets added to my filtered var.

Upvotes: 2

Related Questions