[英]iterate through properties of multiple objects
我正在為我的應用程序開發過濾引擎。 現在,我遇到了對象數據之間的迭代問題,我需要根據用戶應用的過濾器數組進行檢查。 最終目標是返回匹配一個或多個過濾器選項的對象。
這是我的代碼:
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 的形狀這是一個動態過濾器,從空開始然后填充
所以你想從兩個選擇器中獲取狀態並做一些工作,然后返回結果? 這是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'];
我們可以更新 filter 函數以根據 filterArray 值測試 Objects 值。 如果任何屬性值與 filterArray 值匹配,那么我們可以將醫生包含在結果過濾醫生列表中。
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>);
};
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.