为了账号安全,请及时绑定邮箱和手机立即绑定

迭代多个对象的属性

迭代多个对象的属性

慕森王 2023-07-06 15:04:48
我正在为我的应用程序开发一个过滤引擎。现在,我遇到了对象数据之间的迭代问题,我需要根据用户应用的过滤器数组进行检查。最终目标是返回与一个或多个过滤器选项匹配的对象。这是我的代码: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的形状,它是一个动态过滤器,开始为空,然后填充
查看完整描述

1 回答

?
万千封印

TA贡献1891条经验 获得超3个赞

那么您想从两个选择器获取状态并做一些工作,然后返回结果?这是 的完美问题类型reselect。Reselect 是一个帮助程序,可让您记住有关状态选择器的昂贵计算。


https://github.com/reduxjs/reselect


这对你来说可能是这样的。


$ yarn add reselect


import React from 'react';

import { useSelector } from 'react-redux';

import { createSelector } from 'reselect';


const filterArraySelector = (state) => state.filterArray;

const doctorsSelector = (state) => state.doctors;


const filteredDoctorsSelector = createSelector(doctorsSelector, filterArraySelector, (filterArray, doctors) => {

  return doctors.filter((doctor) => {

    return filterArray.all((key) => {

      // Do some comparison here, return true if you want to include the doctor in the results

      return doctor[key] !== undefined;

    });

  });

});


const Results = () => {

  const filteredDoctors = useSelector(filteredDoctorsSelector);


  return filteredDoctors.map((doctor) => <span>{doctor}</span>);

};


替代方案

您可以在每次渲染时简单地过滤医生,而不是使用createSelector记忆过滤。像这样:


const Results = () => {

  const filterArray = useSelector((state) => state.filterArray);

  const doctors = useSelector((state) => state.doctors);


  const filteredDoctors = useMemo(

    () =>

      doctors.filter((doctor) => {

        return filterArray.all((key) => {

          // Do some comparison here, return true if you want to return the doctor

          return doctor[key] !== undefined;

        });

      }),

    [doctors, filterArray]

  );


  return filteredDoctors.map((doctor) => <span>{doctor}</span>);

};


给定一个像这样的值的filterArray:


const filterArray = ['Female', 'English'];

我们可以更新过滤器函数来根据 filterArray 值测试对象值。如果任何属性值与filterArray值匹配,那么我们可以将医生包含在生成的filteredDoctors列表中。


const Results = () => {

  const filterArray = useSelector((state) => state.filterArray);

  const doctors = useSelector((state) => state.doctors);


  const filteredDoctors = useMemo(() => {

    return doctors.filter((doctor) => {

      return filterArray.some((filter) => {

        return Object.values(doctor).some((value) => value === filter);

      });

    });

  }, [doctors, filterArray]);


  return filteredDoctors.map((doctor) => <span>{doctor}</span>);

};


更新:


const Results = () => {

  const filterArray = useSelector((state) => state.filterArray);

  const doctors = useSelector((state) => state.doctors);


  const filteredDoctors = useMemo(() => {

    return doctors.filter((doctor) => {

      return filterArray.some((filter) => {

        return Object.values(doctor).some((value) => {

          // If the attribute value is an array

          if (Array.isArray(value)) {

            return value.some((value) => value === filter);

          }

          // If the attribute value is an object, get the values from the object

          if (typeof value === 'object') {

            return Object.values(value).some((value) => value === filter);

          }

          // By default, expect the value to be a string

          return value === filter;

        });

      });

    });

  }, [doctors, filterArray]);


  return filteredDoctors.map((doctor) => <span>{doctor}</span>);

};


查看完整回答
反对 回复 2023-07-06
  • 1 回答
  • 0 关注
  • 85 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信