【问题标题】:Calculate max and average of JSON API result计算 JSON API 结果的最大值和平均值
【发布时间】:2021-05-16 11:01:17
【问题描述】:

我需要计算averagemax 的评分。

从我的角度来看,这应该使用 mapreduce 来实现此目的,但是,我不确定 JSON 是否具有正确的格式,或者它是否需要任何清理。

const
  myJSON = 
    [ { "page": 1, "totalPages": 2, "data": 
        [ { "title": "Developer 1", "rating": 4.7} 
        , { "title": "Developer 2", "rating": 7.8} 
    ] } ]
  ;
var Max_JSO = myJSON.reduce( (acc, cur )=> ((acc.rating > cur.rating)? acc : cur) );
var Min_JSO = myJSON.reduce( (acc, cur )=> ((acc.rating < cur.rating)? acc : cur) );

var Avg_JSO = myJSON.reduce( (acc, cur, idx, arr )=> {
  let
    sum = acc.rating + cur.rating,
    no = idx +1;
  if (no === arr.length) { sum = sum / no };
  return { 'name': cur.name, 'rating': sum }
});

console.log ('max =',  Max_JSO)  
console.log ('min =',  Min_JSO)  
max = { page: 1, totalPages: 2, data: 
        [ { title: 'Developer 1', rating: 4.7 } 
        , { title: 'Developer 2', rating: 7.8 } 
        ] 
      } 

min = { page: 1, totalPages: 2, data: 
        [ { title: 'Developer 1', rating: 4.7} 
        , { title: 'Developer 2', rating: 7.8} 
        ] 
      } 

我现在正在使用这段代码,但我得到一个奇怪的字符串作为输出:

"max =", "{\&quot;page\&quot;:1,\&quot;totalPages\&quot;:5,\&quot;data\&quot;:[{\&quot;title\&quot;:\&quot;Developer 1\&quot;,\&quot;rating\&quot;:4.7},{\&quot;title\&quot;:\&quot;Developer 2\&quot;,\&quot;rating\&quot;:7.8}]}"
 
"min =", "{\&quot;page\&quot;:1,\&quot;totalPages\&quot;:5,\&quot;data\&quot;:[{\&quot;title\&quot;:\&quot;Developer 1\&quot;,\&quot;rating\&quot;:4.7},{\&quot;title\&quot;:\&quot;Developer 2\&quot;,\&quot;rating\&quot;:7.8}]}"

有没有更好的办法?

另外,我不仅需要从data 键中读取rating,还需要在它之外读取,正如您在var myJSON 上看到的那样

像这样生成json

  {
      "Developer 1": 4.7,
      "Developer 2": 7.8,
  }

MIN 是 Developer 1 和 MAX Developer 2

【问题讨论】:

  • 您想要每个页面或整个 myJSON 数组的最大和最小评分吗?
  • 请提供一个更好的输入和输出示例。如果您想要整个myJSON 数组或myJSON 数组中的每个对象都有一个最大值,这里很难理解。平均值和最小值也是如此。
  • 你的标题是平均和最大评级,你的代码是最小和最大评级逻辑在哪里?
  • 不清楚你到底想要什么......
  • 在计算 maxmin 时。条件不应该是myJSON[0].data.reduce 而不是myJSON.reduce 就像myJSON[0].data.reduce((acc, cur) =&gt; (acc.rating &gt; cur.rating ? acc : cur));

标签: javascript json api


【解决方案1】:

您在实现中遇到的主要问题是您没有考虑到 myJSON 数组的嵌套形状(因此所有 cmets 都会询问您是否需要按页面或组合结果)。

您可以将所有逻辑组合到单个 Array#reduce() 调用中,并使用 map() 您的 myJSON 数组返回每页的聚合结果,或使用 Array#flatMap() 传递所有页面的数组 data 数组用于组合指标。

  myJSON = [
    { "page": 1, "totalPages": 2, "data": [{ "title": "Developer 1", "rating": 4.7 }, { "title": "Developer 2", "rating": 7.8 }] },
    { "page": 2, "totalPages": 2, "data": [{ "title": "Developer 1", "rating": 2.2 }, { "title": "Developer 2", "rating": 3 }] }
  ],

  aggregateData = data => {
    const { min, max, sum, count } = data.reduce((a, datum) => {
      if (datum.rating > a.max.rating) {
        a.max = { ...datum };
      }
      if (datum.rating < a.min.rating) {
        a.min = { ...datum };
      }
      a.sum += datum.rating;
      a.count += 1;
      return a;
    }, { min: { rating: Infinity }, max: { rating: -Infinity }, sum: 0, count: 0 });

    const average = sum / count;

    return { min, max, average };
  },

  resultAll = aggregateData(myJSON.flatMap(({ data }) => data));
  resultByPage = myJSON.map(({ data }) => aggregateData(data)),

console.log('Combined');
console.log(resultAll);
console.log('\nBy page');
console.log(resultByPage);
.as-console-wrapper { max-height: 100% !important; top: 0; }

【讨论】:

  • 太棒了,谢谢@pilchard
【解决方案2】:

使用来自 Andy Polhill 的 answer 解释:

在对象数组中查找属性“Y”值最大的对象

这是计算一页的minmaxaverage 的示例。如果需要对多个页面做,可以先计算每个页面的局部值,然后结合数据,求出大体的值。

const json = {
  "page": 1,
  "totalPages": 2,
  "data": [
    { "title": "Developer 1", "rating": 4.7 },
    { "title": "Developer 2", "rating": 7.8 }, 
  ]
};

const max = json.data.reduce((prev, current) => (prev.rating < current.rating) ? prev : current);

const min = json.data.reduce((prev, current) => (prev.rating > current.rating) ? prev : current);

let avg = 0;
json.data.forEach((el) => avg += el.rating);
avg /= json.data.length;

console.log(max);
console.log(min);
console.log(avg);

【讨论】:

    【解决方案3】:

    这是一种方法:

      const myJSON = [
        {
          page: 1,
          totalPages: 2,
          data: [
            { title: "Developer 1", rating: 4.7 },
            { title: "Developer 2", rating: 7.8 },
          ],
        },
      ];
    
      const Data = myJSON[0].data;
      const result = {};
      Data.forEach((entrie, index) => {
        if (index === 0) {
          result.min = entrie.rating;
          result.max = entrie.rating;
          result.avg = entrie.rating;
        }
        if (index !== 0) {
          result.min = result.min < entrie.rating ? result.min : entrie.rating;
          result.max = result.max > entrie.rating ? result.max : entrie.rating;
          result.avg += entrie.rating;
        }
        if (index + 1 === Data.length) {
          result.avg = result.avg / (index + 1);
        }
      });
      console.log(result);
    

    您也可以使用带有自定义排序函数作为参数传递的排序方法

      const myJSON = [
        {
          page: 1,
          totalPages: 2,
          data: [
            { title: "Developer 1", rating: 4.7 },
            { title: "Developer 2", rating: 7.8 },
          ],
        },
      ];
    
      const Data = myJSON[0].data;
      Data.sort((b, a) => {
        return a.rating - b.rating;
      });
      console.log(Data);
    

    通过改变 a 和 b 的位置,您可以决定是升序还是倒序 然后将第一个元素作为最小值或最大值,将最后一个元素作为最大值或最小值。

    PS:如果您从 api 获取数据,您可能需要先使用 JSON.parse() 解析数据。

    【讨论】:

      【解决方案4】:

      您可以使用 flatMap() 获取开发人员数组,然后对其进行迭代以更新包含评分总和的 stats 对象,以便最终计算平均值

      const devs = myJSON.flatMap(o => o.data)
      
      const stats =  {sum:0, max: devs[0], min: devs[0]};
      
      devs.forEach(dev => {
        const {rating: r} = dev;
        stats.sum += r;
        if (r > stats.max.rating){
            stats.max = dev;
        }else if (r < stats.min.rating){
           stats.min = dev;
        }
      });
      
      stats.avg = stats.sum / devs.length;
      
      console.log(stats)
      <script>
      
      var myJSON = [
      {
          "page": 1,
          "totalPages": 2,
          "data": [{
            "title": "Developer 1",
            "rating": 4.7
        }, {
            "title": "Developer 2",
            "rating": 7.8
        }]
      }];
      
      </script>

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-11-04
        • 1970-01-01
        • 2014-11-20
        • 2014-10-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多