I loop through array of objects Each object contents book title and author name.
I loop through the object to get authors names. without duplicate. beacue there is for exmaple 5 books for same author
<div className="container ">
<div className="row ">
{books.map(book(
<div key={book.id}>
<ul >
<li >
{book.author}
</li>
</ul>
</div>
))}
</div>
</div>
</div>
CodePudding user response:
If you take your data of objects and process them before you map
over them you'll find the task easier.
reduce
over the data to create objects. In each the key is the author name, and the value is an object containing the author name, and an array containing their book titles.
Once the iteration is complete just return an array of object values using Object.values
which you can map
over.
.author { text-transform: capitalize; }
<script src="https://unpkg.com/@babel/standalone@7/babel.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
<div id="react"></div>
<script type="text/babel">
function Example({ data }) {
function processData(data) {
return Object.values(data.reduce((acc, c) => {
// Destructure the author and title from the
// current object
const { author, title } = c;
// If the accumulator doesn't have a key
// that matches the author assign a default
// object to it, and then push in the title
acc[author] ??= { author, titles: [] };
acc[author].titles.push(title);
// Return the accumulator for the
// next iteration
return acc;
}, {}));
}
return (
<div>
<p>{processData(data).map(obj => {
const { author, titles } = obj;
return (
<section className="author">
{author}
<ul>{titles.map(title => <li>{title}</li>)}</ul>
</section>
);
})}</p>
</div>
);
}
const data=[{author:"bob",title:"book1"},{author:"dave",title:"book2"},{author:"nicole",title:"book3"},{author:"nicole",title:"book4"},{author:"bob",title:"book5"},{author:"dave",title:"book6"}];
ReactDOM.render(
<Example data={data} />,
document.getElementById('react')
);
</script>
Additional documentation
CodePudding user response:
If you only display author, you can do like this
books.map(b=>b.author) -> this one extracts only author names
new Set -> this remove duplicate author names
updated:
{[...new Set(books.map(b=>b.author))].map((author => <div key={author}>
<ul >
<li >
{author}
</li>
</ul>
</div>
))}
In case you want to display other properties other than author
[{id:1, author:"tom", anotherImage:"image 1"},{id:2, author:"tom", anotherImage:"image 1"}].filter((v,i,a)=>a.findIndex(v2=>(v2.author===v.author))===i).map((book => <div key={book.id}>
<ul >
<li >
{book.author}
<img src={book.anotherImage}>
</li>
</ul>
</div>
))}
CodePudding user response:
I'm not sure if I get exactly what you want, but I think that you want to select all the authors names without repeating.
One option it's to use the method reduce:
const authors = [{author:"Orwell"}, {author:"Knuth"}, {author:"JJ"}, {author: "JJ"}, {author:"Cormen"}, {author:"Knuth"}]
const unduplicatedIterator = authors.reduce((set, obj) => set.add(obj.author), new Set()).keys()