Estoy tratando de encontrar la forma más sencilla de fusionar esta matriz dinámica usando jQuery.
Este es el resultado que obtengo después de intentar usar .reduce . El objeto Mes/Año es dinámico, el resultado se basa en el rango de fechas.
[ { "ObjectGroupingId": 1, "Jan 2022": "Project1", "Feb 2022": 0, "Mar 2022": 0, "Apr 2022": 0, "May 2022": 0 }, { "ObjectGroupingId": 1, "Jan 2022": 0, "Feb 2022": "Project2", "Mar 2022": 0, "Apr 2022": 0, "May 2022": 0 }, { "ObjectGroupingId": 1, "Jan 2022": 0, "Feb 2022": 0, "Mar 2022": "Project3", "Apr 2022": 0, "May 2022": 0 } ]Lo que estoy tratando de lograr es esto
[ { "ObjectGroupingId": 1, "Jan 2022": "Project1", "Feb 2022": "Project2", "Mar 2022": "Project3" } ]Esto es lo que he probado en jQuery
var monthNames = data .map(function (t) { var monthName = formatMonthYear(t.dynamicHeaderColumn); return monthName; }) .reduce(function (p, t) { if (p.indexOf(t) == -1) p.push(t); return p; }, []); // transform var result = data.reduce(function (p, t) { var monthName = formatMonthYear(t.dynamicHeaderColumn); var existing = p.filter(function (t2) { return t2.objectGroupingId == t.objectGroupingId; }); if (existing.length) { existing[0][monthName] = t.projectName; } else { var n = { ObjectGroupingId: t.objectGroupingId }; monthNames.forEach(function (m) { n[m] = 0; }); n[monthName] = t.projectName; p.push(n); } return p; }, []); return result;es posible? No estoy muy familiarizado con jQuery, todavía lo estoy aprendiendo.
¿Por qué el OP quiere usar jQuery? jQuery apunta principalmente al dominio de consultar y manipular el DOM. La tarea del OP, por el contrario, trata con una única estructura de datos puros y cómo atravesarla/transformarla.
Por lo tanto, el OP debe ceñirse al enfoque original del OP que utiliza métodos de objetos integrados como Array y Object .
El siguiente ejemplo de código proporcionado utiliza dos tareas de reduce anidadas para lograr exactamente el resultado deseado del OP...
function collectGroupedProjectData({ lookup, result }, { ObjectGroupingId, ...restData }) { let groupedData = lookup[ObjectGroupingId]; if (!groupedData) { groupedData = lookup[ObjectGroupingId] = { ObjectGroupingId }; result.push(groupedData); } Object .entries(restData) .reduce((group, [key, value]) => { if (value !== 0) { Object.assign(group, { [key]: value }); } return group; }, groupedData); return { lookup, result }; } const data = [{ ObjectGroupingId: 1, 'Jan 2022': 'Project1', 'Feb 2022': 0, 'Mar 2022': 0, 'Apr 2022': 0, 'May 2022': 0, }, { ObjectGroupingId: 1, 'Jan 2022': 0, 'Feb 2022': 'Project2', 'Mar 2022': 0, 'Apr 2022': 0, 'May 2022': 0, }, { ObjectGroupingId: 1, 'Jan 2022': 0, 'Feb 2022': 0, 'Mar 2022': 'Project3', 'Apr 2022': 0, 'May 2022': 0, }, { ObjectGroupingId: 2, 'Jan 2022': 'Project4', 'Feb 2022': 0, 'Mar 2022': 0, 'Apr 2022': 0, 'May 2022': 0, }, { ObjectGroupingId: 2, 'Jan 2022': 0, 'Feb 2022': 'Project5', 'Mar 2022': 0, 'Apr 2022': 0, 'May 2022': 0, }, { ObjectGroupingId: 2, 'Jan 2022': 0, 'Feb 2022': 0, 'Mar 2022': 'Project6', 'Apr 2022': 0, 'May 2022': 0, }]; const listOfGroupedProjects = data .reduce(collectGroupedProjectData, { lookup: {}, result: [] }).result; console.log({ listOfGroupedProjects }); .as-console-wrapper { min-height: 100%!important; top: 0; }Aquí hay una manera simple de lograr esta tarea usando un diccionario. Le recomiendo que lea sobre cómo funciona un diccionario, ¡son muy útiles!
Solo una explicación rápida del código, en function(e,d) i es el índice y d es el valor. La segunda function(key, value) es un poco diferente. La key devolverá el valor antes de : en lugar de un índice. Esto se debe a que está iterando sobre los valores de un objeto ( { y } definen el inicio y el final del objeto). value devolverá cualquier cosa a la derecha de : .
Actualización: actualicé el código para permitir cualquier número de ObjectGroups, así como una versión de JavaScript puro.
var input = [ { "ObjectGroupingId": 1, "Jan 2022": "Project1", "Feb 2022": 0, "Mar 2022": 0, "Apr 2022": 0, "May 2022": 0 }, { "ObjectGroupingId": 1, "Jan 2022": 0, "Feb 2022": "Project2", "Mar 2022": 0, "Apr 2022": 0, "May 2022": 0 }, { "ObjectGroupingId": 1, "Jan 2022": 0, "Feb 2022": 0, "Mar 2022": "Project3", "Apr 2022": 0, "May 2022": 0, "Jan 1900": 0 }, { "ObjectGroupingId": 2, "Jan 2022": 0, "Feb 2022": 0, "Mar 2022": 0, "Apr 2022": 0, "May 2022": 0, "Jan 1900": "Project10" } ] var currentObjectGrouping = null; var outputListJQuery = []; $.each(input, function(i,d){ $.each(d, function(key, value) { if(key === 'ObjectGroupingId') currentObjectGrouping = value; if(outputListJQuery[currentObjectGrouping] === undefined) outputListJQuery[currentObjectGrouping] = {}; if(value !== 0) { outputListJQuery[currentObjectGrouping][key] = value; } }); }); outputListJQuery = outputListJQuery.filter(function( element ) { return element !== undefined; }) console.log("This is using JQuery!"); console.log(outputListJQuery); //Pure JavaScript var outputListJavascript = []; input.forEach(e => { for (const [key, value] of Object.entries(e)) { if(key === 'ObjectGroupingId') currentObjectGrouping = value; if(outputListJavascript[currentObjectGrouping] === undefined) outputListJavascript[currentObjectGrouping] = {}; if(value !== 0) { outputListJavascript[currentObjectGrouping][key] = value; } } }); outputListJavascript = outputListJavascript.filter(function( element ) { return element !== undefined; }) console.log("This is using only JavaScript!"); console.log(outputListJavascript); <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>En el caso de que tenga varios ObjectGroupingId , el resultado final puede ser un objeto de objetos donde las claves de alto nivel son los valores de ObjectGroupingId y los valores los elementos agregados.
const data = [{"ObjectGroupingId": 1,"Jan 2022": "Project1","Feb 2022": 0,"Mar 2022": 0,"Apr 2022": 0,"May 2022": 0},{"ObjectGroupingId": 1,"Jan 2022": 0,"Feb 2022": "Project2","Mar 2022": 0,"Apr 2022": 0,"May 2022": 0},{"ObjectGroupingId": 1,"Jan 2022": 0,"Feb 2022": 0,"Mar 2022": "Project3","Apr 2022": 0,"May 2022": 0},{"ObjectGroupingId": 2,"Jan 2022": "Project4","Feb 2022": 0,"Mar 2022": 0,"Apr 2022": 0,"May 2022": 0},{"ObjectGroupingId": 2,"Jan 2022": 0,"Feb 2022": "Project5","Mar 2022": 0,"Apr 2022": 0,"May 2022": 0},{"ObjectGroupingId": 2,"Jan 2022": 0,"Feb 2022": 0,"Mar 2022": "Project6","Apr 2022": 0,"May 2022": 0}]; const aggData = data.reduce((acc, {ObjectGroupingId:id,...rest}) => ({...acc,[id]:{...acc[id], ...Object.fromEntries(Object.entries(rest).filter(([k,v]) => v !== 0))}}), {} ); console.log( aggData );