¿Hay alguna manera de fusionar todos estos filtros en uno? ¿O alguna otra forma de hacerlo más efectivo? ¿O simplemente usar for loop?
driving += value.filter((obj) => obj.type === CalendarEventType.MIND && obj.data.practice === 'driving').length; breathWork += value.filter((obj) => obj.type === CalendarEventType.MIND && obj.data.practice === 'breath work').length; meditation += value.filter((obj) => obj.type === CalendarEventType.MIND && obj.data.practice === 'meditation').length; cooking += value.filter((obj) => obj.type === CalendarEventType.MIND && obj.data.practice === 'cooking').length; walking += value.filter((obj) => obj.type === CalendarEventType.MIND && obj.data.practice === 'walking').length; other += value.filter((obj) => obj.type === CalendarEventType.MIND && obj.data.practice === 'other').length;Me parecen muy redundantes.
Actualmente estás haciendo un bucle 6 veces sobre la misma matriz. Puede reducir el tiempo de ejecución con un bucle for simple o reduce:
const counts = value.reduce((acc, el) => { if (el.type !== CalendarEventType.MIND) return acc; acc[el.data.practice] = (acc[el.data.practice] ?? 0) + 1 return acc; }, {});Ejemplo:
const CalendarEventType = { MIND: 1, OTHER: 2 }; const value = [ {type: CalendarEventType.MIND, data: { practice: 'driving' } }, {type: CalendarEventType.MIND, data: { practice: 'breath work' } }, {type: CalendarEventType.OTHER, data: { practice: 'breath work' } }, {type: CalendarEventType.MIND, data: { practice: 'other' } }, {type: CalendarEventType.MIND, data: { practice: 'other' } }, {type: CalendarEventType.OTHER, data: { practice: 'other' } }, ]; const counts = value.reduce((acc, el) => { if (el.type !== CalendarEventType.MIND) return acc; acc[el.data.practice] = (acc[el.data.practice] ?? 0) + 1 return acc; }, {}); console.log(counts);Puede tomar una matriz de valores y usar un solo filtro.
const practices = ['driving', 'breath work', 'meditation', 'cooking', 'walking', 'other']; filter = ({ type, data: { practice } }) => type === CalendarEventType.MIND && practices.includes(practice), result = value.filter(filter), count = values.reduce((sum, o) => sum + filter(o), 0);Una forma posible sería agrupar por data.practice . Dado que no hay una función nativa de "agrupar por", puede implementarla usted mismo (como se describe aquí ), o puede usar una biblioteca como Lodash o Ramda .
Ejemplo, usando groupBy de groupBy :
const filteredItems = value.filter((obj) => obj.type === CalendarEventType.MIND); const groupedItems = groupBy(filteredItems, obj => obj.data.practice); Entonces puedes hacer lo que quieras con groupedItems , por ejemplo:
driving += groupedItems['driving'] ? groupedItems['driving'].length : 0; Tenga en cuenta que si un valor dado para data.practice no está representado en filteredItems , entonces esa clave no estará presente en groupedItems , de ahí la necesidad de verificar esa clave.