如何在 setState 上的对象数组中搜索和筛选



我正在尝试基于对象数组创建搜索,其中反应数据采用以下格式:

const data =  [
{"category 1" : [
{
"name": "Orange",
"desc": "juice, orange, Water"
},
{ 
"name": "Ananas",
"desc": "juice, ananas, water"
}
]
},
{"category 2" : [
{
"name": "Banana Split",
"desc": "Banana, ice cream, chocolat, topping",
"allergens": "nuts"
},
{
"name": "Mango Sticky Rice",
"desc": "Mango, rice, milk",
"allergens": ""
}
]
}
]

我将这些数据存储在useState声明中,以便能够在数据更改时相应地呈现:

const [filteredBySearch, setFilteredBySearch] = useState(data)

我有一个输入,我们可以在其中键入任何内容并在 useState 声明中设置。

目标:

如果我输入我的输入:

"Jui"

输出应为:

console.log(filteredBySearch)
/* output: 
[
{"category 1" : [
{
"name": "Orange",
"desc": "juice, orange, Water"
},
{ 
"name": "Ananas",
"desc": "juice, ananas, water"
}
]
},
{"category 2" : []
}
]*/

示例 2:如果我输入我的输入:

"Orange banana"

输出应为:

console.log(filteredBySearch)
/* output:  [
{"category 1" : [
{
"name": "Orange",
"desc": "juice, orange, Water"
}
]
},
{"category 2" : [
{
"name": "Banana Split",
"desc": "Banana, ice cream, chocolat, topping",
"allergens": "nuts"
}
]
}
]*/

我尝试使用map和filter创建一个新对象,并使用setFilteredBySearch进行设置,但是我什么也得不到,甚至无法创建这个新对象。

这是完整的组件:

import Card from '../components/Card'
import React, { useState } from 'react';

export default function IndexPage({ data, search }) {
//search is the result of input value set on a useState
//Filter categoriesFoods by search
const [FilteredBySearch, setFilteredBySearch] = useState(data)

return (
<div className="main-content">
<div className="card-container">
{
FilteredBySearch.map(function(el, i) {
return (
<div key={i}>
<h2 className="category" id={Object.keys(el)}>{Object.keys(el)}</h2>
{
el[Object.keys(el)].map (function(itm,index){
return <Card key={index} infoItem={itm}/>
})
}
</div>
)
})
}
</div>
<style jsx>{`...`}</style>
</div>
)}

对我有什么想法吗? 非常感谢您的指导!

我认为这就是你要找的。我创建了以下实用程序,用于根据您的要求进行过滤。

const dataObj = [
{
'category 1': [
{
name: 'Orange',
desc: 'juice, orange, Water',
},
{
name: 'Ananas',
desc: 'juice, ananas, water',
},
],
},
{
'category 2': [
{
name: 'Banana Split',
desc: 'Banana, ice cream, chocolat, topping',
allergens: 'nuts',
},
{
name: 'Mango Sticky Rice',
desc: 'Mango, rice, milk',
allergens: '',
},
],
},
]
const checkIfInputMatches = (input, desc) => input.toLowerCase().split(" ").some(o => desc.toLowerCase().includes(o))
const filterByInput = (data, input) => {
let finalResult = [];
data.forEach(d => { 
let keys = Object.keys(d);
let values = Object.values(d);
finalResult = [...finalResult, ...values.map((obj, index) => {
let result = obj.filter(o => checkIfInputMatches(input, o.desc))
return  {[keys[index]]: result}
})]
})
return finalResult
}
console.log(filterByInput(dataObj, 'JUI'))
console.log(filterByInput(dataObj, "orange"))
console.log(filterByInput(dataObj, "rice"))
console.log(filterByInput(dataObj, "Orange banana"))

希望这有帮助。

最新更新