转换对象数组的有效方法

时间:2019-03-15 00:53:27

标签: javascript arrays dictionary stream

我从某些api获得以下数据结构:

response = [{grade: 'A', frequency: 54, percentage: 24},
      {grade: 'B', frequency: 50, percentage: 10},
      {grade: 'C', frequency: 0, percentage: 0},
      {grade: 'D', frequency: 50, percentage: 20},
      ...
    ];

现在,某些UI javascript库要求此数据的格式和显示方式如下:

label: ['A', 'B', 'C', 'D'];
data: [[54,50,0,50],[24,10,0,20]];
series: ['frequency', 'percentage'];

响应对象转换为上述元素的最有效方法是什么?

let label = response.map(data => data.grade);
let freqencyData = response.map(data => data.freqency);
let percentageData = response.map(data => data.percentage);
let data = [freqencyData, percentageData];

这样的事情足够有效吗?请不要以为这是一个示例,并且在我的情况下,响应数据太大,将地图绘制三遍似乎是过大了。 谢谢

2 个答案:

答案 0 :(得分:0)

您可以使用函数reduce在一个循环中构建几乎所需的输出。

  1. label属性与其余属性分开。
  2. 通过特定的属性名称(数据,标签和系列)将值分组。
  3. 对象Set允许您为series保留唯一的字符串。
  4. Object.from将对象Set转换为Array。
  5. Object.values从以下内容中提取:{frequency: [1,2,3], percentage: [1,2,3]}至以下内容:[[1,2,3], [1,2,3]]

let response = [{grade: 'A', frequency: 54, percentage: 24},{grade: 'B', frequency: 50, percentage: 10},{grade: 'C', frequency: 0, percentage: 0},{grade: 'D', frequency: 50, percentage: 20}];
let result = response.reduce((a, {grade: label, ...rest}) => {
  Object.keys(rest).forEach(k => {
    (a.series || (a.series = new Set())).add(k);
    a.data = a.data || {};
    (a.data[k] || (a.data[k] = [])).push(rest[k]);
  });  
  (a.label || (a.label = [])).push(label);
  
  return a;
}, Object.create(null));

result.series = Array.from(result.series);
result.data = Object.values(result.data);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

答案 1 :(得分:0)

您可以做一个老式的循环:

let label = [];
let freqencyData = [];
let percentageData = [];

response.forEach(function(element) {
  label.push(data.grade);
  frequencyData.push(data.frequency);
  percentageData.push(data.percentage);
});

let data = [freqencyData, percentageData];