Serhan Oztekin
Serhan Oztekin

Reputation: 475

How can I get unique array from a collection of nested objects with lodash?

I have the following collection:

"items": [{
                "id": 1,
                "title": "Montrachet",
                "imageUrl": "http://winebuff.com.hk/products_image/3376-Ramonet-ChassagneMontrachetBlanc.jpg",
                "imageUrls": [
                    "http://winebuff.com.hk/products_image/3376-Ramonet-ChassagneMontrachetBlanc.jpg",
                    "http://media.riepenau.com/wines/17973_b.jpg",
                    "http://lorempixel.com/400/400/food/3"         
                ],
                "properties": [
                    {"description" : "Kırmızı Şaraplar Desc"},
                    {"region" :"Bordeaux"},
                    {"age": "16"},
                    {"producer" :"Kayra"},
                    {"grapeType":"Espadeiro"}

                ],
                "priceGlass": "1",
                "priceBottle": "2",
                "year": "1999"

            },

{
                "id": 2,
                "title": "Montrachet2",
                "imageUrl": "http://winebuff.com.hk/products_image/3376-Ramonet-ChassagneMontrachetBlanc.jpg",
                "imageUrls": [
                    "http://winebuff.com.hk/products_image/3376-Ramonet-ChassagneMontrachetBlanc.jpg",
                    "http://media.riepenau.com/wines/17973_b.jpg",
                    "http://lorempixel.com/400/400/food/3"         
                ],
                "properties": [
                    {"description" : "Kırmızı Şaraplar Desc"},
                    {"region" :"Bordeaux"},
                    {"age": "16"},
                    {"producer" :"Kayra"},
                    {"grapeType":"Chardonnay"}

                ],
                "priceGlass": "1",
                "priceBottle": "2",
                "year": "1999",
            }
] 

I want to grab unique grapeTypes from that collection. The returning array shold be ["Chardonnay","Espadeiro"]

What is the best way to do it with lodash?

Upvotes: 1

Views: 2078

Answers (2)

dfsq
dfsq

Reputation: 193301

I think this combination of pluck, map and filter should do it:

var result = _.chain(obj.items).pluck('properties').map(function(obj) {
    return _.filter(obj, function(prop) {
        return prop.grapeType;
    })[0].grapeType;
}).uniq().value();

console.log(result);

Check the demo run below.

// Code goes here

var obj = {
    items: [{
            "id": 1,
            "title": "Montrachet",
            "imageUrl": "http://winebuff.com.hk/products_image/3376-Ramonet-ChassagneMontrachetBlanc.jpg",
            "imageUrls": [
                "http://winebuff.com.hk/products_image/3376-Ramonet-ChassagneMontrachetBlanc.jpg",
                "http://media.riepenau.com/wines/17973_b.jpg",
                "http://lorempixel.com/400/400/food/3"
            ],
            "properties": [{
                    "description": "Kırmızı Şaraplar Desc"
                }, {
                    "region": "Bordeaux"
                }, {
                    "age": "16"
                }, {
                    "producer": "Kayra"
                }, {
                    "grapeType": "Espadeiro"
                }

            ],
            "priceGlass": "1",
            "priceBottle": "2",
            "year": "1999"

        },

        {
            "id": 2,
            "title": "Montrachet2",
            "imageUrl": "http://winebuff.com.hk/products_image/3376-Ramonet-ChassagneMontrachetBlanc.jpg",
            "imageUrls": [
                "http://winebuff.com.hk/products_image/3376-Ramonet-ChassagneMontrachetBlanc.jpg",
                "http://media.riepenau.com/wines/17973_b.jpg",
                "http://lorempixel.com/400/400/food/3"
            ],
            "properties": [{
                    "description": "Kırmızı Şaraplar Desc"
                }, {
                    "region": "Bordeaux"
                }, {
                    "age": "16"
                }, {
                    "producer": "Kayra"
                }, {
                    "grapeType": "Chardonnay"
                }

            ],
            "priceGlass": "1",
            "priceBottle": "2",
            "year": "1999",
        }
    ]
};


var result = _.chain(obj.items).pluck('properties').map(function(obj) {
    return _.filter(obj, function(prop) {
        return prop.grapeType;
    })[0].grapeType;
}).uniq().value();

document.write(JSON.stringify(result));
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.8.0/lodash.js"></script>

UPD. If grapeType can be missing from properties then the script should be

var result = _.chain(obj.items).pluck('properties').map(function(obj) {
    return (_.filter(obj, function(prop) {
        return prop.grapeType;
    })[0] || {}).grapeType;
}).compact().uniq().value();

Upvotes: 2

Adam Boduch
Adam Boduch

Reputation: 11211

Here's one way to do it with lodash:

_(items)
    .pluck('properties')
    .map(function(item) {
        return _.find(item, _.ary(_.partialRight(_.has, 'grapeType'), 1));
    })
    .pluck('grapeType')
    .uniq()
    .value();

First, you get the properties arrays using pluck(). Next, you use find() to get the first object in this array that has a grapeType property. This is done using has(), and partially-applying the argument to build the callback function.

Next, you use pluck() again to get the actual property values. Finally, uniq() ensures there are no duplicates.

Upvotes: 0

Related Questions