【发布时间】:2021-02-15 16:16:40
【问题描述】:
我正在为我的应用开发过滤引擎。现在,我遇到了对象数据之间的迭代问题,我需要检查用户应用的过滤器数组。最终目标是返回匹配一个或多个过滤器选择的对象。
这是我的代码:
const Results = () => {
const [dataStored, setDataStored] = useState([])
const filterArray = useSelector(state => state.filterArray);
const doctors = useSelector(state => state.doctors);
// let doctorsResult = doctors.map(doctor => doctor.indexOf(filterArray) !== -1 )
// let doctorsResult = doctors.map(doctor => {for(let key of Object.keys(doctor)){
// if (key === 'price' || key === 'gender' || key === 'language'){
// // setDataStored([...dataStored, doctor[key]])
// console.log("dataStored",doctor[key])}
// // return (dataStored.indexOf(filterArray) !== -1 )
// }})
let doctorsResult = doctors.map(doctor => {
Object.keys(doctor).forEach((key) => {
if (key === 'price' || key === 'gender' || key === 'language') {
setDataStored([...dataStored, doctor[key]])
console.log("dataStored", dataStored)
}
return (dataStored.indexOf(filterArray) !== -1)
})
})
每个对象都有多个属性,但我只需要检查“价格、性别和语言”值。属性不相等,有些只是字符串,有些是数组。到目前为止,我已经能够使用 for..in 和 forEach 循环通过属性进行迭代。我的问题是,我无法比较和返回任何数据,因为它不是数组,因此 indexOf() 给了我一个错误。当我尝试setDataStored([...dataStored, doctor[key]]) 时,状态进入无限循环。
我对这一切都很陌生。如果有人有更好的方法来实现这一点,我将不胜感激。
编辑:
这是 filterArray 的形状 这是一个动态过滤器,开始是空的,然后被填充
【问题讨论】:
-
您是否在寻找
filter而不是map?此外,对于那个dataStored,您可能只想在循环之前初始化它,然后push对其进行初始化。不要为此使用状态挂钩。 -
filterArray的形状是什么? -
@Bergi 在现场。在一次渲染期间,您将调用
setDataStoredn 次,其中 n 是匹配数。问题是,每次在第一次调用 setDataStored 后,都会使用陈旧的数据。这意味着每个渲染都只是将 一个 项添加到 dataStored,尽管做了所有这些工作。作为一般规则,如果您使用 useState 在组件中计算状态,您希望在备忘录或效果挂钩中进行计算。 -
谢谢@Bergi,你说的很对。您的评论确实帮助我实现了我想要做的事情。感谢其余的 cmets,我意识到我也需要应用一个过滤器函数,这样我就可以返回一个返回 true 的对象数组。
标签: javascript arrays reactjs loops iteration