Как я могу получить уникальный массив из коллекции вложенных объектов с помощью lodash?

У меня есть следующая коллекция:

"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",
            }
] 

Я хочу получить уникальные сорта винограда из этой коллекции. Возвращаемый массив должен быть ["Шардоне","Эспадейро"]

Как лучше всего это сделать с помощью lodash?


person Serhan Oztekin    schedule 29.06.2015    source источник
comment
У lodash есть метод _.uniq, который находит уникальность в массиве. Это будет работать в сингле, поэтому вам нужно объединить properties, а затем применить _.uniq с ключевым словом grapeType.   -  person Mithlesh Kumar    schedule 29.06.2015


Ответы (2)


Я думаю, что эта комбинация выщипывания, карты и фильтра должна сделать это:

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);

Проверьте демонстрационный запуск ниже.

// 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. Если grapeType может отсутствовать в properties, то скрипт должен быть

var result = _.chain(obj.items).pluck('properties').map(function(obj) {
    return (_.filter(obj, function(prop) {
        return prop.grapeType;
    })[0] || {}).grapeType;
}).compact().uniq().value();
person dfsq    schedule 29.06.2015
comment
Спасибо за ответ, работает. Интересно, что, если бы у нас не было никакого массива свойств, и если бы мы поместили в поля, как этот, тип сорта винограда; ценаБокал: 1, ценаБутылка: 2, виноградТип: Шардоне - person Serhan Oztekin; 29.06.2015
comment
Тогда это будет просто _.chain(obj.items).pluck('grapeType').uniq().value(). - person dfsq; 29.06.2015
comment
Благодарю вас! И последний вопрос; если у меня есть этот массив свойств и в нем нет поля GrapeType, как я могу преодолеть это сообщение об ошибке, в котором говорится, что фильтр (...) [0] не определен? - person Serhan Oztekin; 29.06.2015

Вот один из способов сделать это с помощью lodash:

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

Сначала вы получаете массивы properties, используя pluck(). Затем вы используете find(), чтобы получить первый объект в этом массиве со свойством grapeType. Это делается с помощью has() и частичного применения аргумента для создания функции обратного вызова.

Затем вы снова используете pluck(), чтобы получить фактические значения свойств. Наконец, uniq() гарантирует отсутствие дубликатов.

person Adam Boduch    schedule 29.06.2015