Quiero implementar una búsqueda de palabras clave para un campo que se encuentra dentro de la matriz anidada de objetos. ¿Cómo puedo lograrlo?
Datos -
const groupList = [{ "group_name": "General", "trainings": [ { "id": 1, "training_name": "Plural Sight", }, { "id": 2, "training_name": "Google Maps", } ] }]Código -
const [groupsData, setGroupsData] = useState([]); const lowerContains = (str1, str2) => str1 && str2 && str1.toLowerCase().indexOf(str2.toLowerCase()) !== -1; const handleSearch = searchKeyword => { if (searchKeyword && searchKeyword.trim()) { const groupFiltered = groupList.filter(item => item.group_name && lowerContains(item.group_name, searchKeyword)); setGroupsData( groupFiltered ); return; } setGroupsData({ [...groupList] }); }; Actualmente puedo buscar con group_name pero también quiero buscar con training_name dentro de trainings .
Suponiendo que desea conservar el objeto de grupo si la searchKeyword de búsqueda está contenida en el nombre del grupo O en uno de los objetos de nombre de entrenamiento, puede usar .some() . Al usar .some() en trainings , puede comprobar si hay al menos un objeto dentro de la matriz de trainings que contenga un valor training_name que coincida con su búsqueda de palabras clave:
const groupFiltered = groupList.filter(item => (item.group_name && lowerContains(item.group_name, searchKeyword)) || (item.trainings.some(training => lowerContains(training.training_name, searchKeyword))) ); Nota: En los datos de ejemplo que compartió, group_name siempre contiene un valor, por lo que puede eliminar item.group_name && verificar si ese es siempre el caso.
Vea el ejemplo de trabajo a continuación:
const groupList = [{ "group_name": "General", "trainings": [{ "id": 1, "training_name": "Plural Sight", }, { "id": 2, "training_name": "Google Maps", } ] }]; const lowerContains = (x, y) => x.toLowerCase().includes(y.toLowerCase()); const searchKeyword = "Plural"; const groupFiltered = groupList.filter(item => (item.group_name && lowerContains(item.group_name, searchKeyword)) || (item.trainings.some(training => lowerContains(training.training_name, searchKeyword))) ); console.log(groupFiltered);Puede buscar dentro de los trainings si group_name no coincide con la operación Array.prototype.some() en los trainings .
Prueba como a continuación.
const handleSearch = (searchKeyword) => { if (searchKeyword && searchKeyword.trim()) { const groupFiltered = groupList.filter( (item) => (item.group_name && lowerContains(item.group_name, searchKeyword)) || item.trainings.some(({ training_name }) => lowerContains(training_name, searchKeyword) ) ); setGroupsData(groupFiltered); return; } setGroupsData(groupList); };Puede usar el método "Array.some" de javascript.
const containsTraining = (item, keyword) => { return item.some( (training) => training.training_name && lowerContains(training.training_name, keyword) ); };Esto devolverá verdadero si el elemento (un solo grupo) contiene al menos una capacitación que tiene la palabra clave de búsqueda de nombre de capacitación.