1

My problem is that I want to find the category of the every title movie that I want to search. For example

searchInput = Action

outputShown = [Transformer,Dinosaur, Godzilla]

Since I have category that listed as you see below:

    const category = ['Comedy','Classic','Drama','Romance','Science- 
     Fiction','Adult','Sex','Kids','Animation','Cartoon','Action','Storyline','Tragic']

I wanted this TitleItems to have match to my searchinput even if they have different type of category.

    const TitleItems =  {
            imgPath:'', name:'The Office',type:['Comedy','Classic','Romance'],views:"5666",rate:"4.1"
        },
        {
            imgPath:'', name:'Ready Player One',type:['Science-Fiction','Romance','Drama'],views:"7776",rate:"4.2"
        },
        {
            imgPath:'', name:'Interstellar',type:['Science-Fiction','Drama','Romance','Tragic'],views:"10505",rate:"4.5"
        },
        {
            imgPath:'', name:'Transformer',type:['Science-Fiction','Action','Classic','Comedy'],views:"20015",rate:"4.3"
        },
        {
            imgPath:'', name:'Jack N The Giant',type:['Science-Fiction','Action','Adult','Comedy'],views:"12234",rate:"4.2"
        }

As you see this is the searchinput, my only problem here is item.type, Since it have an array I cannot do it as item.type.toLowerCase().includes(search.toLowerCase()), but I can do it as item.type[0].toLowerCase().includes(search.toLowerCase()) because it cannot include a array but what I really wanna do it must be search in that array of every item type of the title. So I wonder how's that gonna work? Anyone idea? I don't know if I ask the right question. Please edit it for me if it's a terrible question.

    const [search,setsearch] = useState("");

    const ListItems = items.filter((item,index) => {
        return (
            item.name.toLowerCase().includes(search.toLowerCase()) ||
            item.views.toLowerCase().includes(search.toLowerCase()) ||
            item.rate.toLowerCase().includes(search.toLowerCase()) || 
            item.type.toLowerCase().includes(search.toLowerCase())
        )   
    }).map((item,index) => {
        return(
            <div>
                <h1 key={index}> 
                    {item.name}, {item.type} {item.views} {item.rate} 
                </h1>

            </div>

        )
    })

And here is the body to show the output

    <input type="text" name='search' placeholder='Search...' value={search} onChange={e => setsearch(e.target.value)} />
     {ListItems}
1
  • You can use regular expressions. (new RegExp( item.type.join( "|" ), "i")).test(search.toLowerCase()) Commented Jan 16, 2022 at 7:13

2 Answers 2

2

You can extend that condition using Array.prototype.some (The some() method tests whether at least one element in the array passes the test implemented by the provided function).

item.type.some(category => category.toLowerCase().includes(search.toLowerCase()))

In your filter condition, update it as below

const [search,setsearch] = useState("");

const ListItems = items.filter((item,index) => {
    return (
        item.name.toLowerCase().includes(search.toLowerCase()) ||
        item.views.toLowerCase().includes(search.toLowerCase()) ||
        item.rate.toLowerCase().includes(search.toLowerCase()) || 
        item.type.some(category => category.toLowerCase().includes(search.toLowerCase()))
    )   
}).map((item,index) => {
    return(
        <div>
            <h1 key={index}> 
                {item.name}, {item.type} {item.views} {item.rate} 
            </h1>

        </div>

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

2 Comments

Can I do item.type.some(item.type => item.type.toLowerCase().includes(search.toLowerCase())) ? just curious
That is also fine. because item inside callback of some is in another scope. But it reduces the readability of your code. It should be like this thenitem.type.some(item => item.toLowerCase().includes(search.toLowerCase()))
0

You need to loop through your list and in that list, add any category that includes that filter text.

You will use two array methods, forEach and some.

Simple explanation for your question:

// example from your scenario
const TitleItems: { id: number, list: string[] }[] = [
    {
        id: 12,
        list: ['1', '2', '3', '4', '5', '6', '7', '8']
    }
]

// the accumulator function that shall be taking in the values that have passed our given test
let accumulator: any[] = []

// first loop through all the items by forEach
TitleItems.forEach((item) => {

// then use a comparison using some, some will return true when any element in it matches the query you put
// the query should be your search string
if (item.list.some(item => item === '12')) {
    accumulator.push(item)
}
})

In the end, your accumulator array will have the values that have passed that condition....

For a very advanced solution that I'd not recommend for a beginner is to use the array reduce function to sort out that case.

Read more about the some method here

2 Comments

this sounds complicated..I don't understand.
but still I will used this thanks.

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.