简体   繁体   English

返回所有匹配元素的数组 Javascript/React

[英]Return an array of all matching elements Javascript/React

I have two arrays authors and posts .我有两个数组authorsposts I want to return the posts arrays with the authors names not their emails, as seen below.我想返回带有作者姓名而不是他们的电子邮件的帖子数组,如下所示。

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

I want to return the posts with the actual name of the authors like this我想像这样返回带有作者实际姓名的帖子

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

Please how can I achieve this in react/javascript?请问如何在 react/javascript 中实现这一点?

EDIT: I forgot to add some really important parts of the question.编辑:我忘了添加问题的一些非常重要的部分。

  1. In the posts array, there are some that have the actual names of the authors (not emails) and these names does not occur in the authors array, for example;例如,在posts数组中,有一些具有作者的实际姓名(不是电子邮件),而这些姓名不会出现在authors 数组中;

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

In this case, I also want to retrieve the name Michael Johnson and retrieve the names of the rest of the authors from the authors array.在本例中,我还想检索Michael Johnson的姓名并从authors 数组中检索其余作者的姓名。

  1. In the authors array, there are extra props that I want to retrieve, such as the userId and avatar .authors数组中,有我想要检索的额外道具,例如userIdavatar In essence the code looks like this;本质上,代码如下所示;

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

EXPECTED OUTPUT预期产出

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

Please how do I retrieve these extra props?请问如何找回这些额外的道具?

This seems like an exercise in javascript map and filter .这似乎是 javascript mapfilter的练习。

Here's an example of how you could do it.这是一个如何做到这一点的示例。 And a codesandbox: https://codesandbox.io/s/agitated-brown-owf67还有一个代码和盒子: https ://codesandbox.io/s/agitated-brown-owf67

Also your email address arrays are formatted weirdly, and since you didn't indicate a reason for that in your question I interpreted it as a typo and fixed them.此外,您的电子邮件地址数组的格式也很奇怪,由于您没有在问题中说明原因,因此我将其解释为打字错误并修复了它们。 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>
  );

One way is to map the posts array into another variable.一种方法是将posts数组映射到另一个变量。 Inside this map function you could use the Array.filter and Array.some methods to return the correct authors like so:在这个 map 函数中,您可以使用Array.filterArray.some方法返回正确的作者,如下所示:

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

    return post;
});

this would create the same array as your posts variable except that the authors array is now an array of objects with names and email properties.这将创建与您的posts变量相同的数组,除了作者数组现在是具有名称和电子邮件属性的对象数组。

By the way: while testing my approach, i noticed your posts array probably is not seperated correctly:顺便说一句:在测试我的方法时,我注意到您的posts数组可能没有正确分隔:

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

Should be:应该:

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

(notice the comma's i placed behind ekong@gmail.com and before marcus@gmail.com. (注意我放在 ekong@gmail.com 后面和 marcus@gmail.com 之前的逗号。

Edit编辑

In react i would store the new variable in a state, while using the useEffect hook to look for changes in both the authors and posts array using the dependency array:在反应中,我会将新变量存储在一个状态中,同时使用 useEffect 钩子使用依赖数组查找 author 和 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]);

basically the same except the React way.除了 React 方式外,基本相同。 Then you could loop through mappedPosts and render the authors directly instead of having to filter through a different array inside your JSX which IMO is not very neat.然后你可以循环遍历mappedPosts并直接渲染作者,而不必在你的JSX中过滤一个不同的数组,IMO不是很整洁。

Edit 2编辑 2

From what i understand is that you want to check if either the email or the actual name of the author has a match inside the authors array with respect to the posts array.据我了解,您想检查电子邮件或作者的实际姓名是否在作者数组中与帖子数组匹配。

This is actually quite easy to do, you just have to extend your statement inside the some function:这实际上很容易做到,你只需要在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]);

If you didn't notice;如果你没有注意到; i've changed up the code a little bit to make it more readable.我对代码进行了一些更改以使其更具可读性。 (store the found posts inside a variable and pass that variable to the setState function instead of alltogether). (将找到的帖子存储在一个变量中并将该变量传递给 setState 函数而不是全部)。

You could have a separate method for filtering out authors and mapping their names like:您可以使用单独的方法来过滤作者并映射他们的姓名,例如:

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

Also, your posts.authors arrays, all have two items, you are missing ' between second and third item.此外,您的posts.authors数组都有两个项目,您在第二个和第三个项目之间缺少'

In react you could use it, something like this:在反应中,您可以使用它,如下所示:

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

This way you could ditch .map in findPostAuthors function, so it wouldn't loop too many times.这样你就可以在findPostAuthors函数中findPostAuthors .map ,这样它就不会循环太多次。

First we can build a map for each email as key and name as value and then use the same to get a new posts array like so :-首先,我们可以为每email构建一个map作为键和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);

If the need is just to create a new array, then here is a sample that converts the array to the desired outcome如果只需要创建一个新数组,那么这里是一个将数组转换为所需结果的示例

 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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM