graphmeter
graphmeter

Reputation: 1125

Function that groups JSON data

I am trying to write a function in javascript that from JSON input data returns the data belonging to a specific group, including the children of that group. The data looks like this:

            [
            {"id":"0", "name":"Person 0"},
            {"id":"1", "name":"Person 1","group":"0"},
            {"id":"2", "name":"Person 2","group":"0"},
            {"id":"3", "name":"Person 3","group":"2"},
            {"id":"4", "name":"Person 4","group":"2"},
            {"id":"5", "name":"Person 5","group":"4"},
            {"id":"6", "name":"Person 6","group":"4"},
            {"id":"7", "name":"Person 7","group":"0"},
            {"id":"8", "name":"Person 8","group":"7"}
            ]

Here, a person in group x belongs to the same group as person with id x.

For example: function(data, group) would return the following for function(data, 2):

            [
            {"id":"3", "name":"Person 3","group":"2"},
            {"id":"4", "name":"Person 4","group":"2"},
            {"id":"5", "name":"Person 5","group":"2"},
            {"id":"6", "name":"Person 6","group":"2"},
            ]

and function(data,0):

            [
            {"id":"1", "name":"Person 1","group":"1"},
            {"id":"2", "name":"Person 2","group":"2"},
            {"id":"3", "name":"Person 3","group":"2"},
            {"id":"4", "name":"Person 4","group":"2"},
            {"id":"5", "name":"Person 5","group":"2"},
            {"id":"6", "name":"Person 6","group":"2"},
            {"id":"7", "name":"Person 7","group":"7"},
            {"id":"8", "name":"Person 8","group":"7"}
            ]

I have tried to loop through the array but that doesn't deal with the subgroups, so I guess I have to do it in a recursive fashion?

Upvotes: 1

Views: 267

Answers (3)

I Hate Lazy
I Hate Lazy

Reputation: 48771

You can .reduce() the data array and concatenate in the sub groups.

function dataForGroup(data, group, refs) {
    if (!refs)
        refs = {};

       // check if it's in the list
    if (refs[group] === true)
        return []; // or you can throw an Error
    else
        refs[group] = true; // first encounter, so add it to the list

    return data.reduce(function(res, obj) {
        return obj.group == group ? 
                   res.concat(obj, dataForGroup(data, obj.id, refs)) : res;
    }, []);
}

Hopefully there are no circular references!

Though I don't understand the group(data, 0) output, and I don't see any sub-group data.

Upvotes: 2

Anoop
Anoop

Reputation: 23208

Iterate through entire data array and filter out items with same group.

    var newArr = [],
    isVisted = []; // using to prevent circular reference.

function getGroup(data, groupId, inside) {
    if (!inside) {
        newArr = [];
        isVisted = [];
    }
    if (isVisted.indexOf(groupId) !== -1) {
        return
    };
    for (var k = 0; k < data.length; k++) {
        if (data[k].group == groupId) {
            newArr.push(data[k])
            getGroup(data, data[k].id, true);
        }
    }

    return newArr;
}

jsfiddle demo

Upvotes: 1

Rikki
Rikki

Reputation: 3528

Because you said using javascript, I did it only with javascript. However there are more easier ways to do such a thing in jquery. I didn't test it, just wrote it, so if it was any problem do not hesitate to comment about it.

function Group(data)
{
    var result = [];

    for (var item in data)
    {
        var group = (item.group) ? item.group : -1;

        if (!result[group])

            result[group] = [];

        result[group].push(item);
    }

    return result;
}

var secondGroup = Group(
    [
        {"id":"0", "name":"Person 0"}, 
        {"id":"1", "name":"Person 1","group":"0"}, 
        {"id":"2", "name":"Person 2","group":"0"}, 
        {"id":"3", "name":"Person 3","group":"2"}, 
        {"id":"4", "name":"Person 4","group":"2"}, 
        {"id":"5", "name":"Person 5","group":"4"}, 
        {"id":"6", "name":"Person 6","group":"4"}, 
        {"id":"7", "name":"Person 7","group":"0"}, 
        {"id":"8", "name":"Person 8","group":"7"} 
    ]
)[2];

Cheers

Upvotes: 0

Related Questions