Tengo estos datos de muestra y quería filtrarlos donde los colores son menos de 20 o iguales a 20:
const data = [ { name: "Item1", colors: { green: 8 } }, { name: "Item2", colors: { green: 7, black: 6 } }, { name: "Item3", colors: { green: 20, yellow: 31, pink: 36 } }, { name: "Item4", colors: { black: 39, red: 21 } }, ];Recreé esto en codesandbox: https://codesandbox.io/s/magical-margulis-yy1moz?file=/src/App.js
Intenté esto:
const data = [{colors: { green: 8 },name: "Item1"},{colors: { Black: 6, Green: 7 },name: "Item2"},{colors: { Green: 20, Yellow: 31, Pink: 36 },name: "Item2"},{colors: { Black: 39, Red: 21 },name: "Item4"}]; const newData = data.filter((item) => { return Object.entries(item.colors).filter((c) => c[1] < 20); }); console.log(newData);No filtra correctamente. Todavía puedo ver todos los artículos incluso si son más de 20
El resultado esperado sería mostrar los datos filtrados:
Item1, green: 8 Item2, Black: 6, Green: 7, Item3, Green: 20creo que el filtro no hará el trabajo aquí porque es un objeto en lugar de una matriz, podemos hacer una combinación de reducir y más métodos para lograr esto, también detecté errores tipográficos en sus datos, así que también los arreglé
const data = [ { colors: { green: 8 }, name: 'Item1', }, { colors: { black: 6, green: 7 }, name: 'Item2', }, { colors: { green: 20, yellow: 31, pink: 36 }, name: 'Item3', }, { colors: { black: 39, red: 21 }, name: 'Item4', }, ]; const res = data.reduce((acc, v) => { const colors = Object.keys(v.colors).filter(c => v.colors[c] <= 20); if (!acc[v.name] && colors.length) { const values = {}; colors.forEach(c => { values[c] = v.colors[c]; }); acc[v.name] = values; } return acc; }, {}); console.log(res); .as-console-wrapper { min-height: 100%!important; top: 0; }Un enfoque posible era reduce dos veces la estructura de datos dada.
El primer ciclo de reducción imita la funcionalidad del filtro. El filtrado directo no funciona, ya que los elementos pueden cumplir solo parcialmente los criterios de mostrar valores de color que son inferiores o iguales a 20 .
Por lo tanto, es necesario (re)crear/ensamblar un elemento de este tipo solo con los pares clave-valor coincidentes, de lo que se ocupa la segunda tarea de reducción en la que se procesan las entradas de Object.entries de un elemento de color y el nuevo elemento de color mediante programación. se agrega a través Object.assign .
Volviendo al primer ciclo de reducción, la decisión final de recopilar (no filtrar del todo) un elemento se toma sobre el objeto de color recién creado. En caso de que este objeto presente al menos una clave, es un objeto válido; por lo tanto, se puede crear un elemento final a partir de los datos del elemento original y el nuevo objeto de color.
const data = [ { name: "Item1", colors: { green: 8 } }, { name: "Item2", colors: { green: 7, black: 6 } }, { name: "Item3", colors: { green: 20, yellow: 31, pink: 36 } }, { name: "Item4", colors: { black: 39, red: 21 } }, ]; console.log( data .reduce((result, { name, colors, ...rest }) => { // (try to) create a new color item // with all the key-value pairs where // `value` meets the OP's criteria. const newColorItem = Object .entries(colors) .reduce((item, [key, value]) => { if (value <= 20) { Object.assign(item, { [key]: value }); } return item; }, {}); // for every created and valid new color item // push a newly created item into the `result` // array where this item's data structure equals // the structure of the currently processed // original item. if (Object.keys(newColorItem).length >= 1) { result .push({ name, colors: newColorItem, ...rest, }); } return result; }, []) ) .as-console-wrapper { min-height: 100%!important; top: 0; }Puede filtrar el valor del color usando array#filter y crear un nuevo objeto de colors e insertarlo en el resultado usando array#reduce .
const data = [ { colors: { green: 8 }, name: "Item1" }, { colors: { Black: 6, Green: 7 }, name: "Item2" }, { colors: { Green: 20, Yellow: 31, Pink: 36 }, name: "Item2" }, { colors: { Black: 39, Red: 21 }, name: "Item4" } ], result = data.reduce((r, o) => { const colors = Object.entries(o.colors).filter(([,val]) => val <= 20); if(colors.length) { r.push({ colors: Object.fromEntries(colors), name: o.name }); } return r; },[]); console.log(result);