0

(React Problem)

Let's say we have array of objects like this:

    const books = [
      {
        author: "Marcel Proust",
        title: "In Search of Lost Time",
        pageNumber: 123,
      },
      {
        author: "James Joyce",
        title: "Ulysses",
        pageNumber: 123,
      },
      {
        author: "Miguel de Cervantes",
        title: "Quixote",
        pageNumber: 123,
      },
      {
        author: "Herman Melville",
        title: "Moby Dick",
        pageNumber: 123,
      },
      {
        author: "William Shakespeare",
        title: "Hamlet",
        pageNumber: 123,
      },
    ];

Also we have an input and state like this:

    const [text, setText] = useState("");

    const handleOnChange = (event) => {
      setText(event.target.value);
    };

    <input value={text} onChange={handleOnChange} />;

Now, I would like to filter this array depends on input text, and [author | title] property.

Example:

If user types 'M', the array of object should look like this:

    const books = [
      {
        author: "Marcel Proust",
        title: "In Search of Lost Time",
        pageNumber: 123,
      },
      {
        author: "Miguel de Cervantes",
        title: "Quixote",
        pageNumber: 123,
      },
      {
        author: "Herman Melville",
        title: "Moby Dick",
        pageNumber: 123,
      },
    ];

...because the author or title start with letter M.

1
  • Please show us your attempt. this isn't a free coding service. Consider reading How to Ask and tour. Commented May 18, 2022 at 15:37

6 Answers 6

1

Please try this out

const books = [
      {
        author: "Marcel Proust",
        title: "In Search of Lost Time",
        pageNumber: 123,
      },
      {
        author: "James Joyce",
        title: "Ulysses",
        pageNumber: 123,
      },
      {
        author: "Miguel de Cervantes",
        title: "Quixote",
        pageNumber: 123,
      },
      {
        author: "Herman Melville",
        title: "Moby Dick",
        pageNumber: 123,
      },
      {
        author: "William Shakespeare",
        title: "Hamlet",
        pageNumber: 123,
      },
    ];

const filterWithAuthorAndTitle = (books, searchParams) => {
  return books.filter(({ author, title }) => {
          const testString = `${author}${title}`.toLowerCase();
        let authorName = author.toLowerCase();
    let bookTitle = title.toLowerCase();
          return testString.includes('m') && (authorName.startsWith('m') || bookTitle.startsWith('m'));
        })
}

let filteredBooks = filterWithAuthorAndTitle(books, 'm');

console.log(filteredBooks);

Sign up to request clarification or add additional context in comments.

Comments

0

Every time the input text changes you can use Array.prototype.filter to filter out the books where the title or the author contains the input text.

Note: I've used String.prototype.includes to calculate the matches but you can use other String methods as well, like String.prototype.startsWith.

const books = [
  { author: "Marcel Proust", title: "In Search of Lost Time", pageNumber: 123 },
  { author: "James Joyce", title: "Ulysses", pageNumber: 123 },
  { author: "Miguel de Cervantes", title: "Quixote", pageNumber: 123 },
  { author: "Herman Melville", title: "Moby Dick", pageNumber: 123 },
  { author: "William Shakespeare", title: "Hamlet", pageNumber: 123 },
];

const App = () => {
  const [searchText, setSearchText] = React.useState("");

  const filteredBooks = books.filter(
    ({ author, title }) =>
      author.toLowerCase().includes(searchText.toLowerCase()) ||
      title.toLowerCase().includes(searchText.toLowerCase())
  );

  return (
    <div>
      <input
        type="text"
        value={searchText}
        onChange={({ target }) => setSearchText(target.value)}
      />
      <ul>
        {filteredBooks.map(({ author, title }) => (
          <li key={title}>
            <strong>{title}</strong> by {author}
          </li>
        ))}
      </ul>
    </div>
  );
};

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<div id="root"></div>

Comments

0

You should use a filter on your books array.

const filtered = books.filter(({author, title}) => author.includes(text) || title.includes(text)

This will filter with your text in ANY position on author or title. So in your example, if you type "S", you will have "William Shakespeare". If you want to search only from the begining, you can use startsWith instead of includes

Comments

0

i think this could work:

books.filter((book) => {
                        if (YOURINPUTVALUE === '') {
                            return book
                        } else if (
                            books.author
                                .toLowerCase()
                                .includes(YOURINPUTVALUE.toLowerCase())
                        ) {
                            return book
                        }
                    })

Comments

0

Try this filter function:

books.filter(({
  author,
  title
}) => author.toLowerCase().includes(text.toLowerCase()) || title.toLowerCase().includes(text.toLowerCase()))

Comments

0

Try the following:

const filteredBooks = books.filter(book => {
  return book.title[0] === text || book.author[0] === text;
})

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.