计算基于 2 个数据的值的出现

问题描述

我有一个看起来像这样的数组:

Arr=[{"cause" : 1,"solution" : "change"},{"cause" : 1,"solution" : "rechange"},{"cause" : 2,"solution" : "alter settings"},{"cause" : 3,{"cause" : 4,{"cause" : 5,"solution" : "reload"}];

我正在尝试根据原因计算解决方案的出现次数,并将其以百分比形式存储在数组中。例如,原因 1 和解决方案更改的发生率为 2/3,因此乘以 100 为 66.66%。 这是我到目前为止的进展:

var ctr = [];
var percentageArr = [];

for (var a=0;a< Arr.length;a++){
    for (var b=0;b< Arr.length;b++){
       if (Arr [b]. cause == Arr [a]. cause){
          ctr++;
       }   
     }     
   ctr=ctr/( Arr.length)*100;
   ctr=ctr.toFixed(2);
   percentageArr.push(ctr);
   ctr=0;
}

现在有了这个输出,我可以得到原因的百分比。但我试图根据原因获得解决方案的百分比。我目前正在考虑添加一个嵌套循环来检查解决方案,但我愿意接受任何建议

解决方法

您可以使用 Array.prototype.reduce 按原因对项目进行分组并计算原因的单个解决方案。

然后您可以通过将解决方案计数除以原因的总计数来计算百分比来更新每个解决方案

var arr = [{
    'cause': 1,'solution': 'change'
  },{
    'cause': 1,'solution': 'rechange'
  },{
    'cause': 2,'solution': 'alter settings'
  },{
    'cause': 3,{
    'cause': 4,{
    'cause': 5,'solution': 'reload'
  }
];

var res = arr.reduce((acc,item,i) => {
  if (!acc[item.cause]) {
    acc[item.cause] = {
      [item.solution]: 1,}
  } else {
    acc[item.cause] = {
      ...acc[item.cause],[item.solution]: (acc[item.cause][item.solution] || 0) + 1
    }
  }
  return acc;
},{});

for (let i in res) {
  const length = Object.values(res[i]).reduce((acc,i) => acc + i,0);
  res[i] = Object.assign(...Object.entries(res[i]).map(([solution,number]) => ({
    [solution]: ((number / length) * 100).toFixed(2)
  })))
}

console.log(res);

有了 ES5,你就可以做到

var arr = [
  {
    cause: 1,solution: 'change',},{
    cause: 1,solution: 'rechange',{
    cause: 2,solution: 'alter settings',{
    cause: 3,{
    cause: 4,{
    cause: 5,solution: 'reload',];

var res = arr.reduce(function (acc,i) {
  if (!acc[item.cause]) {
    acc[item.cause] = {
      [item.solution]: 1,};
  } else {
    acc[item.cause] = Object.assign(
        acc[item.cause],{
          [item.solution]: acc[item.cause][item.solution]? acc[item.cause][item.solution] + 1: 1
        }
      );
  }
  return acc;
},{});

for (let i in res) {
  const length = Object.values(res[i]).reduce(function (acc,i) {
    return acc + i;
  },0);
  for (let j in res[i]) {
    res[i][j] = ((res[i][j] / length) * 100).toFixed(2);
  }
}

console.log(res);