4

I have a JSON array object as follows:

var orders = [{
    orderId: 1,
    firstName: 'John',
    lastName: 'Smith',
    address: {
        street: '123 Main Street',
        city: 'New York',
        zip: 10001
    }
}, {
    orderId: 2,
    firstName: 'John',
    lastName: 'Smith',
    address: {
        street: '456 Main Street',
        city: 'New York',
        zip: 10001
    }
}, {
    orderId: 3,
    firstName: 'John',
    lastName: 'Smith',
    address: {
        street: '123 Main Street',
        city: 'New York',
        zip: 10001
    }
}, {
    orderId: 4,
    firstName: 'John',
    lastName: 'Smith',
    address: {
        street: '123 Main Street',
        city: 'New York',
        zip: 10002
    }
}];

I am trying to use underscore.js to create a new array object, grouped by the address to meet the use case of displaying all orders that have been shipped to 123 Main Street, New York, 1001.

Is underscore.js the right approach to do this? If so, how should I do so? Any hints will be helpful.

amit_g
  • 30,880
  • 8
  • 61
  • 118
orchard
  • 43
  • 4
  • What would be the output of this? Object pointing to arrays? What would you key the objects by? Arrays of Arrays? – Ruan Mendes Dec 01 '14 at 23:02
  • @JuanMendes - the output would be an array of arrays. I'm trying the suggestion you made about _.groupBy now. – orchard Dec 01 '14 at 23:14

2 Answers2

3

See _.groupBy

console.log(_.groupBy(orders, function(obj){
    return obj.address.street + '|' + obj.address.city + '|' + obj.address.zip;
}));

See http://jsfiddle.net/mendesjuan/gc47ruyL/1/

This example assumes you cannot have a | in an address, you may need a better separator, or use JSON.stringify:

console.log(_.groupBy(orders, function(obj){
    return JSON.stringify([obj.address.street, obj.address.city, obj.address.zip]);
}));
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
Ruan Mendes
  • 90,375
  • 31
  • 153
  • 217
  • thanks @JuanMendes - I think groupBy will solve my problem. The JSON I posted above was an over simplified version of what I have so I am trying to put the pieces together. I will update here either way to inform if it works or not. Thanks again - everyone - for the help. – orchard Dec 01 '14 at 23:32
  • 1
    `return JSON.stringify(…)` always works for escaping if you don't want to choose a specific separator. – Bergi Dec 01 '14 at 23:56
  • @Bergi, except that there's no guarantee of the order of properties, two similar objects could end up serializing differently. – Ruan Mendes Dec 02 '14 at 05:14
  • 1
    @JuanMendes: Actually I meant to `stringify` each string on its own, or maybe an array of them, to get a concatenation like in your answer. I didn't even think of the possibility to `JSON.stringify(obj.address)`, which would indeed suffer from the mentioned problem. – Bergi Dec 02 '14 at 11:10
  • @Bergi I still don't see what you mean with using `JSON.stringify` to get the group key. Do you mind maybe editing the answer and adding your alternative? My main concern is the case where you have two objects `{a: "aa", b: "aa"}` and `{a: "a", b: "aaa"}` or `{a: "a|", b: "b"}` and `{a: "a", b: "|b"}` – Ruan Mendes Dec 02 '14 at 14:01
  • @Bergi I see: the quotes around each item make it safe from repeated characters at the edges of properties, and the array keeps the order – Ruan Mendes Dec 02 '14 at 14:09
  • 1
    @JuanMendes - thanks for suggesting to use _.groupBy - it was exactly what I needed. I am a new user here and am amazed by the help I was provided. I will make every effort to contribute back. – orchard Dec 02 '14 at 17:11
  • 1
    @orchard Same thing happened to me 5 years ago, I've been addicted since http://stackoverflow.com/questions/1868333/how-can-i-determine-the-type-of-a-generic-field-in-java – Ruan Mendes Dec 02 '14 at 18:09
2

If you already have underscore in your page, you could use

var filteredOrders = _.filter(orders, function(order){
  return (order.address.street === '123 Main Street') &&
          (order.address.city === 'New York') &&
          (order.address.zip === 10001);
});

Fiddle

amit_g
  • 30,880
  • 8
  • 61
  • 118
  • Thanks @amit_g - that is helpful, but this would work for this specific example where there is only 1 address. The JSON example I posted was representative of an array which could contain multiple users with different addresses. I need to be able to compare the address object across all users, so that I can find all users who share the same address. – orchard Dec 01 '14 at 22:56
  • 1
    @orchard, please update the question with a sample to demonstrate this requirement. – amit_g Dec 01 '14 at 22:59
  • @JordanGray Actually it cannot be easily extended, it's easy if you know what you're searching for, otherwise, some heavy work is needed to find duplicates – Ruan Mendes Dec 01 '14 at 23:03
  • @JuanMendes Good point; I neglected to consider excluding duplicates. Still, I feel that Amit deserves some credit for answering what was asked. :) – Jordan Gray Dec 01 '14 at 23:05
  • @JordanGray - the first thing I tried was to mark the answer as helpful :) but I am a new user and found that I don't have the required reputation (15 points) to do so ... I completely concur Amit's response is very helpful indeed. – orchard Dec 01 '14 at 23:06
  • @amit_g - thanks for the fiddle. It helps and I'm trying to make it meet the requirement I had described above ... – orchard Dec 01 '14 at 23:08
  • @JuanMendes - thanks for the feedback. However in my JSON, I am guaranteed not to have duplicates so filtering those out would not be a concern. You made a perfectly valid point though. – orchard Dec 01 '14 at 23:09
  • @orchard Ah, I see—sorry, I hadn't considered that you might not have the upvote privilege. In that case, please consider my earlier comment fully retracted. – Jordan Gray Dec 01 '14 at 23:09
  • @orchard Both of you misunderstood what I said, my point is that you have to scan the array once, and then find all the objects with the same address, duplicates was not the best word – Ruan Mendes Dec 01 '14 at 23:10