Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/454.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JavaScript数组中对象的分组依据、不同计数、总和_Javascript - Fatal编程技术网

JavaScript数组中对象的分组依据、不同计数、总和

JavaScript数组中对象的分组依据、不同计数、总和,javascript,Javascript,这可能是补救措施,但我想不出来。我曾尝试使用d3和lodash来获得一个有效的解决方案,但没有取得任何进展 我有一个JavaScript对象数组。如果[Selected]值为true,我想创建一个按[Version Name]分组的对象,其中包含不同区域的计数以及每个版本的总计。例如,使用对象 [ { Selcted: false, Version Name: "aaa", Zone: "11111", Value: 5 }, { Selcted: false, Versi

这可能是补救措施,但我想不出来。我曾尝试使用d3和lodash来获得一个有效的解决方案,但没有取得任何进展

我有一个JavaScript对象数组。如果[Selected]值为true,我想创建一个按[Version Name]分组的对象,其中包含不同区域的计数以及每个版本的总计。例如,使用对象

[ 
     { Selcted: false, Version Name: "aaa", Zone: "11111", Value: 5 },
     { Selcted: false, Version Name: "aaa", Zone: "11111", Value: 10 },
     { Selcted: true, Version Name: "aaa", Zone: "11111", Value: 15 },
     { Selcted: true, Version Name: "aaa", Zone: "11111", Value: 20 },
     { Selcted: true, Version Name: "aaa", Zone: "22222", Value: 25 },
     { Selcted: true, Version Name: "bbb", Zone: "22222", Value: 30 },
     { Selcted: true, Version Name: "bbb", Zone: "22222", Value: 35 },
     { Selcted: true, Version Name: "bbb", Zone: "2222", Value: 40 }
]
应该返回

[ 
     { Version Name: "aaa", Zone Count: "2", Value Sum: 50 },
     { Version Name: "bbb", Zone Count: "1", Value Sum: 105 },
]

假设您的数据数组名为
arr

const summed = Object.values(
  arr
    .filter(x => x.Selected)
    .reduce((acc, obj) => {
      if (!acc[obj["Version Name"]) {
        acc["Version Name"] = {
          "Version Name": acc["Version Name"],
          "Zones": new Set(),
          "Value Sum": 0,
        };
      }
      acc["Version Name"]["Value Sum"] += obj.Value;
      acc["Version Name"].Zones.add(obj.Zone);
      return acc;
    })
).map(obj => {
  return {
    "Version Name": obj["Version Name"],
    "Zone Count": obj.Zones.size,
    "Value Sum": obj["Value Sum"],
  };
});

首先,我们过滤掉未选中的对象,并通过对版本名进行散列、聚合值、使用集合跟踪不同区域,按版本名获得不同的对象数组,然后使用
Object.values
将散列返回数组。然后我们将其映射以获得区域计数的每个集合的大小。

这使用了我最喜欢的groupBy函数:)一旦获得了组,您就可以进行另一个组以获得区域计数,并减少以获得总和

简而言之

const byName = groupBy(input.filter(it => it.Selcted), it => it['Version Name'])

const output = Object.keys(byName).map(name => {
  const byZone = groupBy(byName[name], it => it.Zone)
  const sum = byName[name].reduce((acc, it) => acc + it.Value, 0)
  return {
    'Version Name': name,
    ZoneCount: Object.keys(byZone).length,
    ValueSum: sum
  }
})
别忘了,您需要在“Version Name”周围加引号才能将其用作键

下面是一个使用数据集的工作示例

函数分组方式(a,键函数){
常量组={};
a、 forEach(函数(el){
常数键=键功能(el);
如果(输入组===false){
组[键]=[];
}
组[键]。推送(el);
});
返回组;
}
常量输入=[{
选择:错,
'版本名称':“aaa”,
分区:“11111”,
价值:5
},
{
选择:错,
'版本名称':“aaa”,
分区:“11111”,
数值:10
},
{
选择:对,
'版本名称':“aaa”,
分区:“11111”,
价值:15
},
{
选择:对,
'版本名称':“aaa”,
分区:“11111”,
价值:20
},
{
选择:对,
'版本名称':“aaa”,
区域:“22222”,
价值:25
},
{
选择:对,
'版本名称':“bbb”,
区域:“22222”,
价值:30
},
{
选择:对,
'版本名称':“bbb”,
区域:“22222”,
价值:35
},
{
选择:对,
'版本名称':“bbb”,
分区:“2222”,
价值:40
}
]
const byName=groupBy(input.filter(it=>it.selected),it=>it['Version Name'])
const output=Object.keys(byName).map(name=>{
constbyzone=groupBy(byName[name],it=>it.Zone)
const sum=byName[name].reduce((acc,it)=>acc+it.Value,0)
返回{
“版本名”:名称,
ZoneCount:Object.keys(byZone).length,
ValueSum:sum
}
})

console.log(output)
使用
过滤器
获取所需的项目后,您可以分两步执行此操作,首先是
减少
,然后是
映射

let input=[
{selected:false,“版本名”:“aaa”,区域:“11111”,值:5},
{selected:false,“版本名”:“aaa”,区域:“11111”,值:10},
{选择:true,“版本名”:“aaa”,区域:“11111”,值:15},
{选择:true,“版本名”:“aaa”,区域:“11111”,值:20},
{选择:true,“版本名”:“aaa”,区域:“22222”,值:25},
{选择:true,“版本名”:“bbb”,区域:“22222”,值:30},
{选择:true,“版本名”:“bbb”,区域:“22222”,值:35},
{选择:true,“版本名”:“bbb”,区域:“2222”,值:40}
]
var result=input.filter(x=>x.selected)
.减少((会计科目,当前)=>{
让item=acc.find(x=>x.version==curr[“version Name”]);
如果(!项){
项={version:curr[“version Name”],区域:{}
acc.push(项目);
}
item.zones[curr.Zone]=(item.zones[curr.Zone]| | 0)+curr.Value
返回acc;
},[])
.map(x=>({
“版本名称”:x.Version,
“区域计数”:对象。键(x区域)。长度,
“值和”:对象。值(x区域)。减少((a,b)=>a+b,0)
}))
控制台日志(结果)您可以使用和为此创建地图,然后在地图上显示所需的结果。请尝试以下操作:

让arr=[{Selected:false,VersionName:“aaa”,Zone:11111,Value:5},{Selected:false,VersionName:“aaa”,Zone:11111,Value:10},{Selected:true,VersionName:“aaa”,Zone:“11111”,Value:20},{Selected:true,VersionName:“aaa”,Zone:“2222”,Value:25},{Selected:true,VersionName:“bbb”,Zone:“2222”,Value:30},{Selected:true,VersionName:“bbb”,Zone:“2222”,Value:35},{Selected:true,VersionName:“bbb”,Zone:“2222”,Value:40}];
设集合=新集合();
让结果=对象值(arr.reduce((a,curr)=>{
如果(当前选定){
a[curr.VersionName]=a[curr.VersionName]| |{VersionName:curr.VersionName,ZoneCount:0,ValueSum:0};
如果(!set.has(curr.Zone+“”+curr.VersionName)){
a[curr.VersionName].ZoneCount+=1;
set.add(curr.Zone+“”+curr.VersionName);
}
a[curr.VersionName].ValueSum+=curr.Value;
}
返回a;
},{}));

console.log(result);
我认为最简单的解决方案是与

const selectedObjects=objects.filter((i)=>i.Selected==true);
const results=selectedObjects.reduce((项目,对象)=>{
让item=items.find((i)=>i.VersionName===obj[“版本名]);
如果(!项){
const ZoneCount=所选对象
.filter((i)=>i[“版本名”]==obj[“版本名”])
.减少((区域,obj)=>{
if(区域索引of(对象区域)=-1){
推送区(目标区);
}
返回区;
},[])长度;
项目={
ValueSum:0,
版本名:obj[“版本名”],
分区计数
};
项目。推送(项目);
}
item.ValueSum+=目标值;
重新
  Array.prototype.groupBy = function groupBy(key) {
    const hash = {}, result = [];
    for(const el of this) {
       if(hash[ el[key] ]) {
         hash[ el[key] ].push(el);
       } else {
         result.push({
           key: el[key],
           values: hash[ el[key] ] = [ el ],
        });
     }
  }
  return result;
 };

 Array.prototype.key = function(key) {
   return this.map(el => el[key]);
 };

 Array.prototype.sum = function(key) {
  return this.reduce((total, el) => total + (key ? el[key] : el), 0);
 };

 Array.prototype.unique = function() {
   return [...new Set(this)];
 };
  const result = array
       .filter(el =>  el.Selected)
       .groupBy("Version Name")
       .map(({ key, values }) => ({
         "Version Name": key,
         "Value Sum": values.sum("Sum"),
         "Zone Count":values.key("Zone").unique().length,
       }));
let campos = ["classificacao", "count_tables"];
let conteudo = mysql_information_schema[cliente][projeto][dbName].conteudo;
let count = {};
conteudo.forEach( (tabela)=> { //agrupa dentro de count
     count[tabela.classificacao] = count[tabela.classificacao] > 0 ? count[tabela.classificacao] + 1 : 1 ;
});
//converte o objeto para o padrão do array object da view
conteudo =  Object.keys(count).map( (key)=>{return {classificacao: key,  count_tables: count[key]} } );