Carol.Kar
Carol.Kar

Reputation: 5345

lodash: Filtering object in object with pickBy

I am trying to use "lodash": "^4.17.10" to filter an object.

See below my minimum viable example:

const obj = {
    "2": {
        "title": "GeForce GTX 1070 SC GAMING ACX 3.0 Black Edition",
        "category": [{
            "term_id": 34,
            "name": "Graphic Card",
            "slug": "graphic-card",
            "term_group": 0,
        }],
        "currency": "$",
        "price": "547.85",
        "watt": "0",
    },
    "3": {
        "title": "GeForce White Edition",
        "category": [{
            "term_id": 32,
            "name": "other-card",
            "slug": "other-card",
            "term_group": 0,
        }],
        "currency": "$",
        "price": "600.85",
        "watt": "0",
    }
}

let allGpuParts = _.pickBy(obj, (value, key) => {
    return _.startsWith(key.category, "graphic-card")
})

console.log("allGpuParts")
console.log(allGpuParts)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>

As you can currently there is no result returned. I would like to get back only the object "2":, which has the slug "slug": "graphic-card".

Any suggestions how to filter with lodash?

I appreciate your replies!

Upvotes: 1

Views: 3204

Answers (2)

Joe Warner
Joe Warner

Reputation: 3452

You can just use _.filter and _.isMatch to find the key value pair you're looking for _.some just means if any match return true.

const obj = {
    "2": {
        "title": "GeForce GTX 1070 SC GAMING ACX 3.0 Black Edition",
        "category": [{
            "term_id": 34,
            "name": "Graphic Card",
            "slug": "graphic-card",
            "term_group": 0,
        }],
        "currency": "$",
        "price": "547.85",
        "watt": "0",
    },
    "3": {
        "title": "GeForce White Edition",
        "category": [{
            "term_id": 32,
            "name": "other-card",
            "slug": "other-card",
            "term_group": 0,
        }],
        "currency": "$",
        "price": "600.85",
        "watt": "0",
    }
}

const isGPU = o => _.isMatch(o, {slug: "graphic-card"});
const allGpuParts = _.filter(obj, ({category}) => category.some(isGPU));

console.log("allGpuParts")
console.log(allGpuParts)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>

Please let me know if I've misunderstood or if you have any questions.

Upvotes: 1

Paul S.
Paul S.

Reputation: 66324

  • category is an Array of Objects, so you need to iterate it in some way, e.g. by using Array.prototype.some to find if there is any item which meets a condition
  • You need to check against slug itself rather than testing a string-vs-object category

I've kept a startsWith test although your current example would also work with an exact match

const graphicCategory = cat => cat.slug.startsWith('graphic-card'); // true or false test

_.pickBy(
    obj, // your object
    value => value.category.some(graphicCategory) // pick if some category has graphic-card
); // {2: { ... }}

Upvotes: 2

Related Questions