如何根据特定的 属性 值合并数组项?

How to merge array items according to a specific property value?

我正在尝试找到使用 jQuery 合并此动态数组的最简单方法。

这是我尝试使用 .reduce 后得到的结果。 Month/Year 对象是动态的,结果基于日期范围。

[
    {
        "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": 1,
        "Jan 2022": "Project1",
        "Feb 2022": "Project2",
        "Mar 2022": "Project3"
    }
]

这是我在 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;

这可能吗?不是很熟jQuery还在学习

这是使用字典完成此任务的简单方法。我强烈建议您阅读字典的工作原理 - 它们非常有用!

只是对代码的快速解释,在 function(e,d) 中,i 是索引,d 是值。第二个 - function(key, value) 有点不同。 key 将 return : 之前的值而不是索引。这是因为您正在迭代对象的值({} 定义对象的开始和结束)。 value 将 return : 右侧的任何内容。

更新:我更新了代码以允许任意数量的对象组以及纯 JavaScript 版本。

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>

在您有多个 ObjectGroupingId 的情况下,最终结果可以是对象的对象,其中 high-level 键是 ObjectGroupingId 值,值是聚合元素。

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 );

OP 为什么要使用 jQuery? jQuery主要针对查询和操作DOM的域。相比之下,OP 的任务处理单个纯数据结构以及如何 traverse/transform 它。

因此,OP 应该坚持 OP 的原始方法,该方法使用 built-in 对象的方法,例如 ArrayObject

下一个提供的代码示例使用两个嵌套的 reduce 任务以准确实现 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; }