使用reduce构建一个比较两个数组的数组对象

3

我想要绘制一张图表,但数据需要按特定方式格式化。我最终将数据转换为正确的形式,但发现有一些值缺失。

我有一个日期数组:

const labels = ["Sep.08", "Sep.09", "Sep.12", "Sep.13", "Sep.14"]

我有一个包含namedatecount的对象数组:

const Data = [
{date: "Sep.08", name: "User1", count: 8},
{date: "Sep.08", name: "User2", count: 2},
{date: "Sep.09", name: "User2", count: 3},
{date: "Sep.09", name: "User3", count: 1},
{date: "Sep.12", name: "User1", count: 11},
{date: "Sep.13", name: "User1", count: 3},
{date: "Sep.13", name: "User2", count: 3},
{date: "Sep.14", name: "User2", count: 7},
]

我想要达成的目标:

  1. 每个姓名都应该在新对象中有一个数组
  2. 每个日期都应该在数组中表示,以便每个数组具有相同的长度。如果用户没有表示标签数组中某个日期的对象,则应在新数组的该索引处添加零。

我的期望结果是:

const result = {
User1: [8,0,11,3,0], //0's where user has no object with the dates of "Sep.09" & "Sep.14"
User2: [2,3,0,3,7],
User3: [0,1,0,0,0],
}

我正在使用.reduce来创建我的新对象:

const Data = [
{date: "Sep.08", name: "User1", count: 8},
{date: "Sep.08", name: "User2", count: 2},
{date: "Sep.09", name: "User2", count: 3},
{date: "Sep.09", name: "User3", count: 1},
{date: "Sep.12", name: "User1", count: 11},
{date: "Sep.13", name: "User1", count: 3},
{date: "Sep.13", name: "User2", count: 3},
{date: "Sep.14", name: "User2", count: 7},
]

const labels = ["Sep.08", "Sep.09", "Sep.12", "Sep.13","Sep.14"]


const groups = Data.reduce((acc, obj) => {
 
  if (!acc[obj.name]) {
    acc[obj.name] = [];
  }
 
  acc[obj.name].push(obj.count);

  return acc;
}, {});

console.log(groups)

问题是我不确定如何将标签与acc对象中的名称进行比较。对我来说,reduce非常令人困惑,但它似乎是我需要格式化数据的最简洁方式。任何建议都会有所帮助。
2个回答

3
你可以这样做:

const Data = [{date:"Sep.08",name:"User1",count:8},{date:"Sep.08",name:"User2",count:2},{date:"Sep.09",name:"User2",count:3},{date:"Sep.09",name:"User3",count:1},{date:"Sep.12",name:"User1",count:11},{date:"Sep.13",name:"User1",count:3},{date:"Sep.13",name:"User2",count:3},{date:"Sep.14",name:"User2",count:7},];
const labels = ["Sep.08","Sep.09","Sep.12","Sep.13","Sep.14"];

const groups = Data.reduce((acc, { date, name, count }) => {
  if (!acc[name]) {
    // Fill an array with zeroes, the length of labels
    acc[name] = labels.map(_ => 0);
  }
  // Find the index of the current label
  const labelIndex = labels.indexOf(date);
  // Replace the corresponding zero
  acc[name][labelIndex] = count;
  
  return acc;
}, {});


console.log(groups);


1
我会先进行第一轮循环,以查找所有日期和用户。然后针对每个日期,在用户上循环以构建他们的数组。
const dictionary = {};
const users = new Set();
Data.forEach(({date, name, count}) => {
  if (!dictionary[date]) dictionary[date] = {};
  // for each date, store users and their count when available
  dictionary[date] = {[name]: count};
  // keep track of existing users
  users.add(name);
}
const result = {};
// convert the user set to an array
const userArray = Array.from(users);
// populate an array of count for each user
userArray.forEach(user => result[user] = []);

Object.entries(dictionary).forEach(([date, userCountMap]) => {
  userArray.forEach(user => {
    // for each date, populate the count of each user, or put 0 if there is no count
    result[user].push(userCountMap[user] || 0);
  });
});
console.log(result);


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接