返回所有匹配元素的数组javascript/react

hs1rzwqc  于 2021-09-23  发布在  Java
关注(0)|答案(5)|浏览(241)

我有两个数组 authorsposts . 我想返回带有作者姓名的帖子数组,而不是他们的电子邮件,如下所示。

const authors = [
  {name: 'Thompson Smith', email: 'thompson@gmail.com'},
  {name: 'John Doe', email: 'doe@gmail.com'},
  {name: 'Jane Coker', email: 'jane@gmail.com'},
  {name: 'Mirabel Ekong', email: 'ekong@gmail.com'},
  {name: 'Samuel Doe', email: 'samuel@gmail.com'},
  {name: 'Moses Philips', email: 'moses@gmail.com'},
  {name: 'Marcus Bowa', email: 'marcus@gmail.com'},
  {name: 'Peter Touch', email: 'touch@gmail.com'},
  {name: 'Benson Bruce', email: 'bruce@gmail.com'},
]

const posts = [
  { title: 'title one', authors: ['doe@gmail.com', 'ekong@gmail.com', 'marcus@gmail.com'] },
  { title: 'title two', authors: ['bruce@gmail.com', 'moses@gmail.com', 'marcus@gmail.com'] },
  { title: 'title three', authors: ['samuel@gmail.com', 'touch@gmail.com', 'bruce@gmail.com'] },
  { title: 'title four', authors: ['thompson@gmail.com', 'jane@gmail.com', 'samuel@gmail.com'] },
]

我想用作者的真实姓名返回帖子,如下所示

<div>
  <h2>{post.title}</h2>
  <p>
    <span>{post.author.name}</span>
    <span>{post.author.name}</span>
    <span>{post.author.name}</span>
  </p>
</div>

请问如何在react/javascript中实现这一点?
编辑:我忘了在问题中添加一些非常重要的部分。
posts 数组中,有些具有作者的实际姓名(不是电子邮件),例如,这些姓名不出现在作者数组中;

{ title: 'title one', authors: ['Michael Johnson', 'ekong@gmail.com', 'marcus@gmail.com'] }

在本例中,我还希望检索名称 Michael Johnson 并从authors数组中检索其余作者的姓名。
authors 数组中,我想检索一些额外的道具,例如 userIdavatar . 本质上代码是这样的;

const authors = [
  {name: 'Thompson Smith', email: 'thompson@gmail.com', userId: '001', avatar: '/avatar/1'},
  {name: 'John Doe', email: 'doe@gmail.com', userId: '002', avatar: '/avatar/2'},
  {name: 'Jane Coker', email: 'jane@gmail.com', userId: '003', avatar: '/avatar/3'},
  {name: 'Mirabel Ekong', email: 'ekong@gmail.com', userId: '004', avatar: '/avatar/4'},
  {name: 'Samuel Doe', email: 'samuel@gmail.com', userId: '005', avatar: '/avatar/5'},
  {name: 'Moses Philips', email: 'moses@gmail.com', userId: '006', avatar: '/avatar/6'},
  {name: 'Marcus Bowa', email: 'marcus@gmail.com', userId: '007', avatar: '/avatar/7'},
  {name: 'Peter Touch', email: 'touch@gmail.com', userId: '008', avatar: '/avatar/8'},
  {name: 'Benson Bruce', email: 'bruce@gmail.com', userId: '009', avatar: '/avatar'}
]

const posts = [
  { title: 'title one', authors: ['doe@gmail.com', 'ekong@gmail.com', 'marcus@gmail.com'] },
  { title: 'title two', authors: ['bruce@gmail.com', 'moses@gmail.com', 'marcus@gmail.com'] },
  { title: 'title three', authors: ['samuel@gmail.com', 'touch@gmail.com', 'bruce@gmail.com'] },
  { title: 'title four', authors: ['thompson@gmail.com', 'jane@gmail.com', 'samuel@gmail.com'] },
  { title: 'title five', authors: ['michael Johnson', 'jane@gmail.com', 'samuel@gmail.com'] },
  { title: 'title six', authors: ['michael Johnson', 'Jane Joshua', 'samuel@gmail.com'] },
]

预期产量

<div>
  <h2>{post.title}</h2>
  <ul>
    <li><Link to={userId}><Avatar src={avatar}/>{post.author.name}</Link></li>
    <li><Link to={userId}><Avatar src={avatar}/>{post.author.name}</Link></li>
    <li><Link to={userId}><Avatar src={avatar}/>{post.author.name}</Link></li>

//If the author does not exist in the authors array, should return
 <li><placeHolderAvatar />{post.author.name}</li>
  </ul>
</div>

请问我如何取回这些额外的道具?

x8goxv8g

x8goxv8g1#

一种方法是绘制Map posts 数组插入另一个变量。在这个Map函数中,您可以使用 Array.filterArray.some 返回正确作者的方法如下:

let mappedPosts = posts.map(post => {
    post.authors = authors.filter(author => post.authors.some(a => a === author.email));

    return post;
});

这将创建与您的 posts 变量,但authors数组现在是具有名称和电子邮件属性的对象数组。
顺便说一下:在测试我的方法时,我注意到你的 posts 阵列可能未正确分离:

{ title: 'title one', authors: ['doe@gmail.com', 'ekong@gmail.com, marcus@gmail.com'] },

应该是:

{ title: 'title one', authors: ['doe@gmail.com', 'ekong@gmail.com', 'marcus@gmail.com'] },

(注意我放在后面的逗号。)ekong@gmail.com之前marcus@gmail.com.
编辑
在react中,我将新变量存储在一个状态中,同时使用useeffect钩子使用依赖项数组查找authors和posts数组中的更改:

let [mappedPosts, setMappedPosts] = useState([]);

useEffect(() => {
    if (authors && posts) {
        setMappedPosts(posts.map(post => {
            post.authors = authors.filter(author => post.authors.some(a => a === author.email));
            return post;
        }));
    }
}, [authors, posts]);

基本相同,只是React方式不同。然后你可以循环通过 mappedPosts 并直接呈现作者,而不必通过jsx中的不同数组进行过滤,因为imo并不十分整洁。
编辑2
据我所知,您需要检查电子邮件或作者的实际姓名是否在authors数组中与posts数组匹配。
这实际上很容易做到,只需在 some 功能:

let [mappedPosts, setMappedPosts] = useState([]);

useEffect(() => {
    if (authors && posts) {
        let foundPosts = posts.map(post => {
            post.authors = authors.filter(author => {
                return post.authors.some(a => {
                    return a === author.email || a === author.name;
                });
            });
            return post;
        });
        setMappedPosts(foundPosts);
    }
}, [authors, posts]);

如果你没有注意到;我对代码做了一些修改,使其更具可读性(将找到的POST存储在一个变量中,并将该变量传递给setstate函数,而不是一起传递)。

k10s72fa

k10s72fa2#

您可以使用单独的方法筛选作者并Map他们的姓名,如:

function findPostAuthors(post) {
    return authors
    .filter(({email}) => post.authors.includes(email))
    .map(({name}) => name);
}

还有,你的 posts.authors 数组,都有两项,您缺少 ' 在第二项和第三项之间。
在react中,您可以使用它,类似这样的内容:

return (
    <div className="App">
      {posts.map((post) => (
        <div>
          <h2>{post.title}</h2>
          <p>
            {findPostAuthors(post)
              .map(author => (<span>{author}</span>))}
          </p>
        </div>
      ))}
    </div>
  );

这样你就可以放弃 .map 在里面 findPostAuthors 函数,所以它不会循环太多次。

ttisahbt

ttisahbt3#

如果只需要创建一个新数组,那么下面是一个将数组转换为所需结果的示例

let authors = [
  {name: 'Thompson Smith', email: 'thompson@gmail.com'},
  {name: 'John Doe', email: 'doe@gmail.com'},
  {name: 'Jane Coker', email: 'jane@gmail.com'},
  {name: 'Mirabel Ekong', email: 'ekong@gmail.com'},
  {name: 'Samuel Doe', email: 'samuel@gmail.com'},
  {name: 'Moses Philips', email: 'moses@gmail.com'},
  {name: 'Marcus Bowa', email: 'marcus@gmail.com'},
  {name: 'Peter Touch', email: 'touch@gmail.com'},
  {name: 'Benson Bruce', email: 'bruce@gmail.com'},
]

let posts = [
  { title: 'title one', authors: ['Michael Johnson', 'ekong@gmail.com', 'marcus@gmail.com'] },
  { title: 'title two', authors: ['bruce@gmail.com', 'moses@gmail.com', 'marcus@gmail.com'] },
  { title: 'title three', authors: ['samuel@gmail.com', 'touch@gmail.com', 'bruce@gmail.com'] },
  { title: 'title four', authors: ['thompson@gmail.com', 'jane@gmail.com', 'samuel@gmail.com'] },
]

posts = posts.map(obj => ({ ...obj, authors: obj.authors.map(email => authors.find(auth => auth.email === email)?.name ? authors.find(auth => auth.email === email)?.name : email )}))

console.log(posts)
1cosmwyk

1cosmwyk4#

首先,我们可以建立一个 map 每人 email 作为关键和 name 作为值,然后使用相同的值获取新的 posts 像这样排列:-

const authors = [{
    name: 'Thompson Smith',
    email: 'thompson@gmail.com',
    userId: '001',
    avatar: '/avatar/1'
  },
  {
    name: 'John Doe',
    email: 'doe@gmail.com',
    userId: '002',
    avatar: '/avatar/2'
  },
  {
    name: 'Jane Coker',
    email: 'jane@gmail.com',
    userId: '003',
    avatar: '/avatar/3'
  },
  {
    name: 'Mirabel Ekong',
    email: 'ekong@gmail.com',
    userId: '004',
    avatar: '/avatar/4'
  },
  {
    name: 'Samuel Doe',
    email: 'samuel@gmail.com',
    userId: '005',
    avatar: '/avatar/5'
  },
  {
    name: 'Moses Philips',
    email: 'moses@gmail.com',
    userId: '006',
    avatar: '/avatar/6'
  },
  {
    name: 'Marcus Bowa',
    email: 'marcus@gmail.com',
    userId: '007',
    avatar: '/avatar/7'
  },
  {
    name: 'Peter Touch',
    email: 'touch@gmail.com',
    userId: '008',
    avatar: '/avatar/8'
  },
  {
    name: 'Benson Bruce',
    email: 'bruce@gmail.com',
    userId: '009',
    avatar: '/avatar'
  }
]

const posts = [{
    title: 'title one',
    authors: ['doe@gmail.com', 'ekong@gmail.com', 'marcus@gmail.com']
  },
  {
    title: 'title two',
    authors: ['bruce@gmail.com', 'moses@gmail.com', 'marcus@gmail.com']
  },
  {
    title: 'title three',
    authors: ['samuel@gmail.com', 'touch@gmail.com', 'bruce@gmail.com']
  },
  {
    title: 'title four',
    authors: ['thompson@gmail.com', 'jane@gmail.com', 'samuel@gmail.com']
  },
  {
    title: 'title five',
    authors: ['michael Johnson', 'jane@gmail.com', 'samuel@gmail.com']
  },
  {
    title: 'title six',
    authors: ['michael Johnson', 'Jane Joshua', 'samuel@gmail.com']
  },
]

const nameEmailMap = authors.reduce((acc, {
  name,
  email,
  userId,
  avatar
}) => {
  acc[email] = {
    name,
    userId,
    avatar
  };
  return acc;
}, {})

const newPosts = posts.map(({
  title,
  authors
}) => ({
  title,
  authors: authors.map(entry => (nameEmailMap[entry] ? { ...nameEmailMap[entry]
  } : {
    name: entry
  }))
}));

console.log(newPosts);
x7yiwoj4

x7yiwoj45#

这似乎是javascript中的一个练习 mapfilter .
下面是一个例子,说明了如何做到这一点。和一个代码沙盒:https://codesandbox.io/s/agitated-brown-owf67
此外,您的电子邮件地址数组的格式也很奇怪,因为您在问题中没有说明原因,所以我将其解释为键入错误并修复了它们。ymmv。

return (
    <div className="App">
      {posts.map((p) => (
        <div>
          <h2>{p.title}</h2>
          <p>
            {p.authors
              .map((a) =>
                authors
                  .filter((author) => author.email === a)
                  .map((author) => author.name)
              )
              .map(a => (<span>{a}</span>))}
          </p>
        </div>
      ))}
    </div>
  );

相关问题