根据 2 个数据计算值的出现

Calculating the Occurrence of a Value based on 2 data

我有一个如下所示的数组:

Arr=[{"cause" : 1 , "solution" : "change"}, 
     {"cause" : 1 , "solution" : "rechange"}, 
     {"cause" : 2 , "solution" : "alter settings"}, 
     {"cause" : 1 , "solution" : "change"}, 
     {"cause" : 3 , "solution" : "change"},
     {"cause" : 4 , "solution" : "change"}, 
     {"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': 1,
    'solution': 'change'
  },
  {
    'cause': 3,
    'solution': 'change'
  },
  {
    'cause': 4,
    'solution': 'change'
  },
  {
    '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: 1,
    solution: 'change',
  },
  {
    cause: 3,
    solution: 'change',
  },
  {
    cause: 4,
    solution: 'change',
  },
  {
    cause: 5,
    solution: 'reload',
  },
];

var res = arr.reduce(function (acc, item, 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);