[英]Return an array of all matching elements Javascript/React
I have two arrays authors
and posts
.我有两个数组
authors
和posts
。 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.编辑:我忘了添加问题的一些非常重要的部分。
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 数组中检索其余作者的姓名。
authors
array, there are extra props that I want to retrieve, such as the userId
and avatar
.authors
数组中,有我想要检索的额外道具,例如userId
和avatar
。 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
map
和filter
的练习。
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.filter
和Array.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.