Tengo datos como a continuación,
const arr_obj = [ { id: '1', children: [], type: 'TYPE1', }, { id: '2', children: [ { id: '1', children: [ { //some attributes } ], type: 'MAIN', }, { id: '2', children: [ { //some attributes } ], type: 'MAIN', }, { id: '3', children: [ { //some attributes } ], type: 'MAIN', }, ] type: 'TYPE2', }, { id: '3', children: [ { id: '4', children: [ { //some attributes } ], type: 'MAIN', }, { id: '5', children: [ { //some attributes } ], type: 'MAIN', }, { id: '6', children: [ { //some attributes } ], type: 'MAIN', }, ] type: 'TYPE2', } ]Tengo que averiguar el recuento de tipo: 'MAIN'. estos 'MAIN' estarán dentro del tipo: "type2"
Entonces el conteo esperado es 6.
a continuación se muestra el código,
const ParentComponent = () => { const findCount = (arr_obj) => { let count = 0; const expectedCount = 2; const loop = (children) => { for (const obj of children) { const { type, children } = obj; if (type === 'TYPE2') { loop(children); } else if (type === 'MAIN') { ++count; if (count > expectedCount) return; } } }; loop(children); return count > expectedCount; }; const output = findCount(arr_obj); return ( //some jsx rendering ); }el código anterior funciona bien. pero quiero hacer que la función de bucle (niños) sea una función pura. No estoy seguro de cómo hacerlo.
el problema ahora es que defino variables fuera del método de bucle. ¿Cómo puedo definir todo como argumentos para la función? Podría mover la función fuera del componente.
Podría alguien ayudarme con esto. Gracias.
Puede tomar una matriz del orden del tipo deseado e iterar solo un nivel y pasar el resto del tipo deseado. Si no queda ningún tipo, devuelve uno, de lo contrario, el resultado del recuento anidado.
const getCount = (array, types) => { let count = 0; for (const { type, children } of array) { if (types[0] === type) { count += types.length === 1 ? 1 : getCount(children, types.slice(1)); } } return count; } data = [{ id: '1', children: [], type: 'TYPE1' }, { id: '2', children: [{ id: '1', children: [{}], type: 'MAIN' }, { id: '2', children: [{}], type: 'MAIN' }, { id: '3', children: [{} ], type: 'MAIN' }], type: 'TYPE2' }, { id: '3', children: [{ id: '4', children: [{}], type: 'MAIN' }, { id: '5', children: [{}], type: 'MAIN' }, { id: '6', children: [{}], type: 'MAIN' }], type: 'TYPE2' }], order = ['TYPE2', 'MAIN'], count = getCount(data, order); console.log(count);Pure Function es una función (un bloque de código) que siempre devuelve el mismo resultado si se pasan los mismos argumentos. No depende de ningún estado o cambio de datos durante la ejecución de un programa, sino que solo depende de sus argumentos de entrada.
En el código compartido anterior, pude ver la cuenta esperada como la variable compartida que no es la función PURE.
Como pude ver en sus comentarios, el tipo deseado está en Niños, entonces son solo los 2 niveles. Entonces el siguiente código funcionaría.
function count(data, condition) { let count = 0; data.forEach((value, index) => { if(value.type === condition[0]){ value.children.forEach((val, idx) => { if(val.type === condition[1]) { count++; } }) } }); return count; } const condition = ['TYPE2', 'MAIN']; console.log(count(arr_obj, condition));La respuesta de Nina es más precisa, pero también podría hacerlo filtrando la matriz de entrada.
const data = [{ id: '1', children: [], type: 'TYPE1' }, { id: '2', children: [{ id: '1', children: [{}], type: 'MAIN' }, { id: '2', children: [{}], type: 'MAIN' }, { id: '3', children: [{} ], type: 'MAIN' }], type: 'TYPE2' }, { id: '3', children: [{ id: '4', children: [{}], type: 'MAIN' }, { id: '5', children: [{}], type: 'MAIN' }, { id: '6', children: [{}], type: 'MAIN' }], type: 'TYPE2' }]; const count = data .filter(v=>v.type==='TYPE2') .flatMap(v=>v.children) .filter(v=>v.type==='MAIN') .length console.log(count);