Home > Enterprise >  How to search filter array item inside the array
How to search filter array item inside the array

Time:01-16

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}

CodePudding user response:

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>

    )
})

CodePudding user response:

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

  •  Tags:  
  • Related