1

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?

1
  • lodash has method _.uniq which find uniqueness within array. This will work in single, so you need to merge properties and then apply _.uniq with keyword grapeType. Commented Jun 29, 2015 at 11:10

2 Answers 2

2

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();
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you for the answer, it works. I wonder what if we didn't have any "properties" array and if we put grapeType like this in the fields; "priceGlass": "1", "priceBottle": "2", "grapeType": "Chardonney"
Then it would be just _.chain(obj.items).pluck('grapeType').uniq().value().
Thank you! One last question; if i have this "properties" array and there's no grapeType field in it, how can i overcome this error message saying "filter(...)[0] is undefined"?
0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.