Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lodash: filter then map over an object

Im trying to filter out objects with a delete: false to then only map and render this objects to screen but I'm not sure how to get it to work.

Sample object

{
  "8xf0y6ziyjabvozdd253nd": {
    "id": "8xf0y6ziyjabvozdd253nd",
    "timestamp": 1467166872634,
    "title": "Udacity is the best place to learn React",
    "body": "Everyone says so after all.",
    "author": "thingtwo",
    "category": "react",
    "voteScore": 6,
    "deleted": false
  }
}

Method for finding key and map.

const {posts} = this.props
        return _.find(posts, { 'deleted': false })_.map(posts, post => {
            return (
                <div key={post.id}>
like image 905
Petter Östergren Avatar asked Sep 14 '17 21:09

Petter Östergren


1 Answers

Basically, you can apply lodash#reduce to Object directly instead of getting all the keys first, and then iterating again. And with reduce you can do the map and filtering together.

_.reduce(obj, (i, v, k)=> !v.deleted && !(i[k] = v) || i, {});

Let's create a working example for you, Here is a code snippet:

var obj = {
  "9ny0z4ziyjabvozdc713dr": {
    "id": "9ny0z4ziyjabvozdc713dr",
    "timestamp": 1467166879723,
    "title": "StackOverfow is the best place to learn Angular",
    "body": "bla bla bla bla.",
    "author": "myself",
    "category": "angular",
    "voteScore": 9,
    "deleted": true
  },
    "8xf0y6ziyjabvozdd253nd": {
    "id": "8xf0y6ziyjabvozdd253nd",
    "timestamp": 1467166872634,
    "title": "Udacity is the best place to learn React",
    "body": "Everyone says so after all.",
    "author": "thingtwo",
    "category": "react",
    "voteScore": 6,
    "deleted": false
  }
}

var finalObj =_.reduce(obj, (i, v, k)=> !v.deleted && !(i[k] = v) || i, {});

console.log(finalObj);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>

EDIT

For the specific case (of OP), just some key/value pair needs to be removed and construct a new object, then better to use lodash#omitBy to simply remove some entries from an object against some condition. Here is a simple example of this particular use.

_.omitBy(obj, o=>o.deleted);

Here is the code snippet for this example:

var obj = {
      "9ny0z4ziyjabvozdc713dr": {
        "id": "9ny0z4ziyjabvozdc713dr",
        "timestamp": 1467166879723,
        "title": "StackOverfow is the best place to learn Angular",
        "body": "bla bla bla bla.",
        "author": "myself",
        "category": "angular",
        "voteScore": 9,
        "deleted": true
      },
        "8xf0y6ziyjabvozdd253nd": {
        "id": "8xf0y6ziyjabvozdd253nd",
        "timestamp": 1467166872634,
        "title": "Udacity is the best place to learn React",
        "body": "Everyone says so after all.",
        "author": "thingtwo",
        "category": "react",
        "voteScore": 6,
        "deleted": false
      }
    }

    var finalObj =_.omitBy(obj, o=>o.deleted);

    console.log(finalObj);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>

However, If any transformation needed in between (Array or Object), or the output type needs to be customized then I will still prefer to suggest to use reduce.

like image 173
Koushik Chatterjee Avatar answered Oct 10 '22 14:10

Koushik Chatterjee