Lodash: 对对象进行筛选过滤和映射处理

7

我正在尝试筛选出具有 delete: false 属性的对象,然后仅将这些对象映射和渲染到屏幕上,但我不确定如何使其正常工作。

示例对象

{
  "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
  }
}

寻找密钥和映射的方法。
const {posts} = this.props
        return _.find(posts, { 'deleted': false })_.map(posts, post => {
            return (
                <div key={post.id}>
5个回答

8

基本上,你可以直接将 lodash#reduce 应用于对象,而不是先获取所有键,然后再进行迭代。使用 reduce,你可以同时进行映射和过滤。

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

让我们为您创建一个工作示例,这是一个代码片段:

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>

编辑

针对OP的具体情况,只需要删除一些键值对并构造一个新对象,最好使用lodash#omitBy来根据某些条件从对象中简单地删除一些条目。下面是这种特定用法的简单示例。

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

以下是此示例的代码片段:

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>

然而,如果需要在数组或对象之间进行任何转换,或者需要自定义输出类型,则我仍然建议使用reduce。


2

如果你想要过滤,最简单的方法是使用一个实际的过滤器。我不太熟悉React,但是下面的Lodash链式操作可以工作,如果React支持更复杂的链式操作。

我注意到你有一个嵌套的对象,如果这是有意的,那么下面的代码就可以解决问题:

// I added some fake posts to make the data more illustrative 

let posts = [{
    "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
    }
}, {
    "8888ziyjabvozdd253nd": {
        "id": "8888ziyjabvozdd253nd",
        "timestamp": 1467166872634,
        "title": "Udacity is the best place to learn React",
        "body": "Everyone says so after all.",
        "author": "thingtwo",
        "category": "react",
        "voteScore": 6,
        "deleted": true
    }
}, {
    "77776ziyjabvozdd253nd": {
        "id": "77776ziyjabvozdd253nd",
        "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
    }
}, {
    "6666ziyjabvozdd253nd": {
        "id": "6666ziyjabvozdd253nd",
        "timestamp": 1467166872634,
        "title": "Udacity is the best place to learn React",
        "body": "Everyone says so after all.",
        "author": "thingtwo",
        "category": "react",
        "voteScore": 6,
        "deleted": true
    }
}, {
    "55556ziyjabvozdd253nd": {
        "id": "55556ziyjabvozdd253nd",
        "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
    }
}];

// you'd just return _(posts) here directly, but I'm assigning a variable so we can show the console log for this snippet
const filteredPosts = _(posts)
    .filter(post => {
        const objectKey = Object.keys(post)[0];
        const innerData = post[objectKey];
        return innerData.deleted === false
    })
    .map(post => {
        const objectKey = Object.keys(post)[0];
        // your return would be in the format of <div key={objectKey}>
      return  `<div key={${objectKey}}>`
    })
    .valueOf();




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

如果对象的嵌套不是有意为之,那么获取信息将更加简单和清晰。如果您的实际对象看起来像我下面提供的示例对象,您可以像这样访问数据:

let posts = [{
        "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
}, {
        "id": "8888ziyjabvozdd253nd",
        "timestamp": 1467166872634,
        "title": "Udacity is the best place to learn React",
        "body": "Everyone says so after all.",
        "author": "thingtwo",
        "category": "react",
        "voteScore": 6,
        "deleted": true
}, {
        "id": "77776ziyjabvozdd253nd",
        "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
}];

// you'd just return _(posts) here directly, but I'm assigning a variable so we can show the console log for this snippet
const filteredPosts = _(posts)
    .filter(post => {
        return post.deleted === false
    })
    .map(post => {
        // your return would be in the format of <div key={post.id}>
      return  `<div key={${post.id}}>`
    })
    .valueOf();




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


1
< p > _.find 的结果是一个数组,因此如果您想要对该数组中的元素进行map操作,您应该使用_.map(result)

const {posts} = this.props;
return _.map(_.find(posts, { 'deleted': false }), post => {
            return (
                <div key={post.id}>

1
如果您想跳过lodash,JavaScript数组的原生API将为您提供以下解决方案:
const { posts } = this.props;

return posts
    .find(post => !post.deleted)
    .map(post => {
        return (
            <div key={post.id}>...

在回答这个问题的时候我没有看到你的答案。无论如何,我稍微编辑了我的答案@Dekel - SALEH
1
这个答案是错误的。posts.find 应该获取一个函数... 而不是元素和对象。在发布之前请再次确认。 - Dekel
@Dekel,这不是内联函数的语法吗?它不需要参数的括号(因为只有一个参数),也不需要函数代码的花括号(因为它只有一行)。 - Brendon Muir
@BrendonMuir 我的评论是在回答编辑之前的 :-) - Dekel
你在那里没错 :D - Brendon Muir
2
这是错误的。find返回单个实例或者如果没有匹配则返回undefinedmap可用于数组上。map不能像这样链式使用。 - Matt Byrne

0

你可以用以下方式做到

let obj = {
  "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
  }
}

let result = Object.keys(obj).reduce((a, b) =>{
    if(obj[b].deleted != false){
        a[b] = obj[b];
    }
    return a;
}, {});

console.log(result);


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接