操作 Array 对象

manipulating Array object

提问人:grabrep gg 提问时间:10/17/2023 更新时间:10/19/2023 访问量:53

问:

我有下面的数组对象

var datasource = [
                  {"Region": "America",
                   "Total_Time_Spent": "10",
                   "YearMonth": "2023 - October",
                   "projectname":"Project 1"},
                  {"Region": "America",
                   "Total_Time_Spent": "20",
                   "YearMonth": "2023 - October",
                   "projectname":"Project 2"},
                  {"Region": "America",
                   "Total_Time_Spent": "30",
                   "YearMonth": "2023 - June",
                   "projectname":"Project 3"},
                  {"Region": "Asia",
                   "Total_Time_Spent": "30",
                   "YearMonth": "2023 - June",
                   "projectname":"Project 4"}
                 ]

基于上述内容,我正在尝试创建波纹管阵列格式

var Finaldatasource = [
                  {"Region": "America",
                   "YearMonth": "2023 - October",
                   "Project 1": "10",
                   "Project 2": "20",
                   "Project 3": "0",
                   "Project 4": "0"},
                  {"Region": "Asia",
                   "YearMonth": "2023 - October",
                   "Project 1": "0",
                   "Project 2": "0",
                   "Project 3": "0",
                   "Project 4": "0"}
                  {"Region": "America",
                   "YearMonth": "2023 - June",
                   "Project 1": "0",
                   "Project 2": "0",
                   "Project 3": "30",
                   "Project 4": "0"},
                   {"Region": "Asia",
                   "YearMonth": "2023 - June",
                   "Project 1": "0",
                   "Project 2": "0",
                   "Project 3": "0",
                   "Project 4": "30"}
                 ]

表示前两列变为 Region 和 YearMonth,后跟项目名称作为列,value 将是花费的小时数

我已经编写了下面的代码,我能够获取区域,然后是项目名称作为列,值将是花费的小时数。但如何也可以包括 YearMonth 列

var Finaldatasource = [];

datasource.forEach(entry => {
  let existingRegion = result.find(Region => Region.Region === entry.Region);
  
  if (existingRegion) {
    existingRegion[entry.projectname] = entry.Total_Time_Spent;
  } else {
    let newRegion = { "Region": entry.Region };
    newRegion[entry.projectname] = entry.Total_Time_Spent;
    result.push(newRegion);
  }
});

// Add missing months and set their values to 0
var allMonths = Array.from(new Set(dataarray.map(entry => entry.projectname)));

result.forEach(Region => {
  allMonths.forEach(month => {
    if (!Region.hasOwnProperty(month)) {
      Region[month] = 0;
    }
  });
});
JavaScript jQuery 数组

评论


答:

1赞 HighDevWizards 10/17/2023 #1

我有你要找的东西。 如果您使用 es6,则可以简单地完成。

var datasource = [
  {"Region": "America",
   "Total_Time_Spent": "10",
   "YearMonth": "2023 - October",
   "projectname":"Project 1"},
  {"Region": "America",
   "Total_Time_Spent": "20",
   "YearMonth": "2023 - October",
   "projectname":"Project 2"},
  {"Region": "America",
   "Total_Time_Spent": "30",
   "YearMonth": "2023 - June",
   "projectname":"Project 3"},
  {"Region": "Asia",
   "Total_Time_Spent": "30",
   "YearMonth": "2023 - June",
   "projectname":"Project 4"}
 ];
 
 var project = {
   "Project 1": "0",
   "Project 2": "0",
   "Project 3": "0",
   "Project 4": "0"
 };
 const newDataSource = datasource.reduce((res, current) => {
    return [
      ...res, 
      {
        "Region": current.Region, 
        "YearMonth": current.YearMonth, 
        ...project,
        [current.projectname]: current.Total_Time_Spent
      }
    ];
 }, []);
 
 console.log(newDataSource)
             

评论

0赞 grabrep gg 10/17/2023
感谢这项工作,但项目名称将是动态的,它不会总是项目 1 到 4,我们可以拥有项目 5、6 等。但无论如何,这对我有用。我知道如何从这里继续前进。谢谢。
0赞 HighDevWizards 10/17/2023
如果项目名称是动态的,则可以先获取它们。
0赞 Nick Parsons 10/17/2023
这看起来是一个更好的情况,而不是因为您几乎正在执行映射操作,但目前使用reduce。.map().reduce()
1赞 Arleigh Hix 10/19/2023 #2

下面是一个函数,可以将数据编译为所需的格式:process()

const datasource = [{
    "Region": "America",
    "Total_Time_Spent": "10",
    "YearMonth": "2023 - October",
    "projectname": "Project 1"
  },
  {
    "Region": "America",
    "Total_Time_Spent": "20",
    "YearMonth": "2023 - October",
    "projectname": "Project 2"
  },
  {
    "Region": "America",
    "Total_Time_Spent": "30",
    "YearMonth": "2023 - June",
    "projectname": "Project 3"
  },
  {
    "Region": "Asia",
    "Total_Time_Spent": "30",
    "YearMonth": "2023 - June",
    "projectname": "Project 4"
  }
]

const proccess = function(input) {
  // start with an object template
  const temp = {
    "Region": null,
    "YearMonth": null
  }
  // add all the project names to the object template as keys with the default value
  Array.from(new Set(input.map(o => o.projectname))).forEach(pn => temp[pn] = "0")
  // define a function that returns a clone of the above template object
  const getObjectTemplate = () => structuredClone(temp)
  
  const results = []
  input.forEach(data => {
    let item = results.find(o => (o.Region === data.Region && o.YearMonth === data.YearMonth))
    const isNew = ("undefined" === typeof item);
    item ??= getObjectTemplate()
    item.Region ??= data.Region
    item.YearMonth ??= data.YearMonth
    item[data.projectname] = data.Total_Time_Spent
    if (isNew)
      results.push(item)
  })

  return results
}

document.querySelector('#op').innerHTML = JSON.stringify(proccess(datasource), null, 1)
<pre><code id="op"></code></pre>