Javascript 给定维度上数组数据的聚合

Javascript 给定维度上数组数据的聚合,javascript,algorithm,data-structures,Javascript,Algorithm,Data Structures,请原谅n00b的问题,但我对数据结构是新手。我最近被要求将一个给定数组聚合到另一个数组上,并生成一个基于树的结果 有人能给我一些关于如何获得这个输出的建议吗 输入 输出:每个叶节点使用2*空格 TOTAL 29900 Female <Female Total> Single <Single Female Total> India <Single Female Total India> England <Single F

请原谅n00b的问题,但我对数据结构是新手。我最近被要求将一个给定数组聚合到另一个数组上,并生成一个基于树的结果

有人能给我一些关于如何获得这个输出的建议吗

输入

输出:每个叶节点使用2*空格

TOTAL 29900
  Female <Female Total>
    Single <Single Female Total>
      India <Single Female Total India>
      England <Single Female Total England>
    Married <Married Female Total>
      India <Married Female Total India>
      England <Married Female Total England>
  Male <Male Total>
    Single <Single Male Total>
      India <Single Male Total India>
      England <Single Male Total England>
    Married <Married Male Total>
      India <Married Male Total India>
      England <Married Male Total England>
总计29900
女性
单身
印度
英格兰
已婚的
印度
英格兰
男性
单身
印度
英格兰
已婚的
印度
英格兰

结果可以用嵌套对象表示,每个内部对象都是一个子树,其总数为:

{
  total: 29900,
  Female: {
    total: 10300,
    Single: {
      total: 4000,
      India: {
        total: 2400
      },
      ...
    },
    ...
  },
  ...
}
只需循环遍历所有then条目,并将值添加到相应的子树节点

对于输出,可以使用
JSON.stringify
并从中删除不必要的文本

警告:下面是扰流板
const T=[
[‘国家’、‘性别’、‘婚姻状况’、‘销售’],
[‘印度’、‘女性’、‘单身’,2400],
[“印度”,“男性”,“单身”,5200],
[“印度”,“女性”,“已婚”,4300],
[‘印度’、‘男性’、‘单身’,3200],
[‘英格兰’、‘女性’、‘单身’,1600],
[‘英格兰’、‘女性’、‘已婚’,2000年],
[“英格兰”,“男性”,“单身”,4800],
[“英格兰”,“男性”,“已婚”,6400],
]
常数A=[“性别”、“婚姻状况”、“国家”]
函数聚合(T,A){
常量[字段,…数据]=T
const columns=A.map(name=>fields.findIndex(it=>name==it))
常量计数=fields.length-1
常量结果={total:0}
data.forEach(值=>{
result.total+=值[计数]
//通过树路径,这里使用reduce
//避免为当前位置创建额外的跟踪变量
列。减少((参考,索引)=>{
常量键=值[索引]
const next=ref[key]| |(ref[key]={total:0})
next.total+=值[计数]
下一个返回
},结果)
})
返回结果
}
功能包(数据){
返回Object.keys(数据).reduce((结果,键)=>{
如果(键!=“总计”){
常量名称=键+“”+数据[键]。总计
结果[名称]=数据包(数据[键])
}
返回结果
}, {})
}
函数格式(结果){
返回JSON.stringify(pack(result),null,2)
.替换(/[^A-z0-9\n\s]/g')
.替换(/\n?\s*\n/g,“\n”)
}
功能输出(it){
const result=“TOTAL”+it.TOTAL+格式(it)
console.log(结果)
}

输出(聚合(T,A))
处理树结构的常用方法是将它们表示为嵌套对象,如所示,然后从此数据结构创建字符串表示

在OP提供的示例中,另一种方法是首先对数据进行排序,然后直接从排序后的数据创建树的字符串表示,而不需要嵌套对象的任何中间数据结构

给定要聚合的列的数组

['GENDER', 'MARITAL STATUS', 'COUNTRY']
我们可以按以下列对数据进行排序:

GENDER   STATUS   COUNTRY   SALES
Female   Single   India     2400
Female   Single   England   1600
Female   Married  India     4300
Female   Married  England   2000
Male     Single   India     5200
Male     Single   England   4800
Male     Married  India     3200
Male     Married  England   6400
从最后一行向后循环,在聚合时,我们可以从下到上构建树的字符串表示。最后一行与第3级(国家/地区)的前一行不同,后者提供以下输出:

      England 6400
前面的行在级别3(国家)和级别2(婚姻状况)上有所不同,并在当前输出之前:

    Married 9600
      India 3200
      England 6400
在前一行之后:

      England 4800
    Married 9600
      India 3200
      England 6400
然后,第5行与前一行在所有3个级别上都有所不同:

  Male 19600
    Single 10000
      India 5200
      England 4800
    Married 9600
      India 3200
      England 6400
以此类推,直到整个树被表示:

Total 29900
  Female 10300
    Single 4000
      India 2400
      England 1600
    Married 6300
      India 4300
      England 2000
  Male 19600
    Single 10000
      India 5200
      England 4800
    Married 9600
      India 3200
      England 6400
下面是工作代码(符合ES3),演示了该方法

var T=[
[‘国家’、‘性别’、‘婚姻状况’、‘销售’],
[‘印度’、‘女性’、‘单身’,2400],
[“印度”,“男性”,“单身”,5200],
[“印度”,“女性”,“已婚”,4300],
[“印度”,“男性”,“已婚”,3200],
[‘英格兰’、‘女性’、‘单身’,1600],
[‘英格兰’、‘女性’、‘已婚’,2000年],
[“英格兰”,“男性”,“单身”,4800],
[“英格兰”,“男性”,“已婚”,6400],
];
变量A=[‘性别’、‘婚姻状况’、‘国家’];
var valueField=‘销售’;
//性别升迁
//婚姻状况下降
//国家下降
var sortDirection=[1,-1,-1];
函数查找(arr、val){
对于(变量i=0;ib[列]?
-排序方向[i]:0);
}
返回比较;
});
//循环数据行、输出树节点
对于(i=0;i-1;级别--){
总和[级别]=(总和[级别]| | 0)+值;
如果(i==data.length-1 | |
记录[groupBy[level]!=数据[i+1][groupBy[level]]){
//输出树节点
结果:推(
数组(级别+2)。连接(“”)
记录[groupBy[level]]+''+
总额[水平];
//重置级别聚合
总和[水平]=0;
}
}
}
结果。推送(“总计”+总计);
result.reverse();
返回结果。join('\n');
}
console.log(
buildTreeString(T、A、排序方向、valueField)

);树是实现此问题的一个好选项。您还可以一次性完成聚合。基本思想是

  • 按给定列对数据进行排序

  • 循环数组,检查给定列的值

    2.1集团总成本
    Total 29900
      Female 10300
        Single 4000
          India 2400
          England 1600
        Married 6300
          India 4300
          England 2000
      Male 19600
        Single 10000
          India 5200
          England 4800
        Married 9600
          India 3200
          England 6400