Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I have array which holds a lot of objects in the following format:

var data = [
  {
    vs: "23434",
    ip: "129.23.321.5"
  },
  {
    vs: "23454",
    ip: "129.23.321.6"
  },
  {
    vs: "23434",
    ip: "129.23.321.8"
  }
];

Now I want to sort them in a way where there is an array that holds objects in the following format:

var dataFinal = [
  {
    vs: "23434",
    ip: ["129.23.321.5", "129.23.321.8"]
  }
  {
    vs: "98647",
    ip: ["129.23.321.6"]
  }
];

So basically, the data var will have multiple objects in it where there could be multiple ip with the same vs. I want to sort them in a way where an array will have multiple objects, one each for each vs, but the ip will be another array that will contain all the ip's for that vs.

What would be the best way to do this in javascript?

share|improve this question
1  
Did you mean "there could be multiple ip with the same vs"? –  merlin Jun 16 at 3:35
    
@merlin yes, thank you for noticing. i have updated the post. –  KSubedi Jun 16 at 3:37
1  
What have you tried? It'd appear that some combination of reduce and sort should work. –  pdoherty926 Jun 16 at 3:39
    
@pdoherty926 so far I have tried creating a temporary object and looping through the data var to find other objects with same vs and grabbing all the ip's and adding it to the temporary object. once the loop is done, it will push the object to dataFinal array, and then do the same for the next vs. this does work but i do not feel like this is the right way to do it. thank you for the suggestions, i will take a look into reduce and sort –  KSubedi Jun 16 at 3:43
    
Try using underscore.js something like _.groupBy(data, 'vs') –  Sreekesh Okky Jun 16 at 4:11

2 Answers 2

up vote 2 down vote accepted

I think this is a programming technique issue that is not related to a specific language.

Javascript does not provide a "native" way to do such kind of task. The way you describe in you comment is totally fine. If you find yourself dealing with these kind of tasks very often, you could use some third party libraries like underscore to reduce bioplate codes.

The underscore way to solve this:

function mergeVsUseUnderscore(data) {
    var dataFinal = [],
    vsInFinal;

    _.each(data, function(item) {
        vsInFinal = _.find(dataFinal, function(itemFinal) {
            return itemFinal.vs === item.vs;
        });

        if(vsInFinal) {
            vsInFinal.ip.push(item.ip);
        } else {
            dataFinal.push({
                vs: item.vs,
                ip: [item.ip]
            })
       }
    });

    return dataFinal;
}

One more thing to mention, simply use _.groupBy(data, 'vs') will produce:

{ 
    '23434': [ 
        { vs: '23434', ip: '129.23.321.5' },
        { vs: '23434', ip: '129.23.321.8' } 
    ],
    '23454': [ { vs: '23454', ip: '129.23.321.6' } ] 
}
share|improve this answer
    
Thank you, i ended up using _.groupBy –  KSubedi Jun 17 at 6:19
var data = [{
    vs: "1",
    ip: "129.23.321.6"
}, {
    vs: "2",
    ip: "129.23.321.8"
}, {
    vs: "0",
    ip: "129.23.321.5"
}, ];

var transformed = data.reduce(function (memo, datum) {

    var filterFunc = function (_datum) {

        return datum.vs === _datum.vs;

    };

    if (!memo.some(filterFunc)) {

        memo.push({
            vs: datum.vs,
            ip: [datum.ip]
        });

    } else {

        memo.filter(filterFunc)[0].ip.push(datum.ip)

    }

    return memo;

}, []);

var sorted = transformed.sort(function (a, b) {

    if (a.vs > b.vs) {

        return 1;

    } else if (a.vs < b.vs) {

        return -1;

    } else {

        return 0;

    }

});

console.log(JSON.stringify(sorted));

Fiddle

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.