使用ramda group by属性和sum指定属性的结果 [英] using ramda group by property and sum results on specified property

查看:158
本文介绍了使用ramda group by属性和sum指定属性的结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要帮助使用ramda转换对象数组;我想按指定的财产


  1. 分组

  2. 加上$ b上的另一个属性给定一个这样的数组:

      var arr = [
    {
    title:scotty,
    age:22,
    得分:54,
    爱好:调试

    },{
    title:scotty,
    年龄:22,
    得分:19,
    爱好:调试
    }
    ,{
    title:gabriel,
    年龄:40,
    得分:1000
    }
    ];

    如果我想按 title 进行分组,总和年龄它应返回以下值摘要

      var arr = [
    {
    title:scotty,
    年龄:44,
    爱好:调试,
    }
    ,{
    标题:gabriel,
    年龄:40,
    得分:1000
    }
    ];

    当未指定的属性值不同时,应省略它们,但如果未指定的属性值相同它应保留在最终结果中。



    **我的解决方案**

      / * 
    * [学生]
    * /
    var arr = [
    {
    title:scotty,
    年龄:22岁,
    得分:54,
    爱好:调试

    },{
    标题:scotty,
    年龄:22,
    得分:19,
    爱好:调试
    }
    ,{
    标题:gabriel,
    年龄:40,
    得分:1000
    }
    ];


    / *
    *字符串 - > [[学生]] - > [学生]
    * /
    var sumOnProperty = function(property,v){
    var sum =(x,y)=> x [property] + y [property];
    var new_array = [];
    v.forEach(arr => {
    if(arr.length> 1){
    arr [0] [age] = arr.reduce(sum)
    new_array.push(arr [0]);
    } else {
    if(arr.length!= 0){
    new_array.push(arr [0]);
    }
    }
    })
    返回new_array;
    }

    / *
    *字符串 - >字符串 - > [学生] - > [学生]
    * /
    var groupsumBy = function(groupproperty,sumproperty,arr){

    //创建分组
    var grouping = R.groupBy(R。 prop(groupproperty),arr)

    //将分组对象转换为数组
    var result1 = R.valuesIn(分组);

    //对每个分组求和并展平2d数组
    var result2 = sumOnProperty(sumproperty,result1);

    返回result2;
    }


    groupsumBy(title,age,arr);


    解决方案

    修复 groupBy 您需要看到 groupBy 采用密钥生成函数函数而不是二元谓词。



    因此,例如,

      const byTitle = R.groupBy(R.prop('title')); 

    这可以帮助您完成当前的阻止。如果您在总结方面需要帮助,请与我们联系。



    更新



    你问我的做法。它与你的确有所不同。我可能会这样做:

      const sumBy = prop => vals => reduce(
    (当前,val)=> evolve({[prop]:add(val [prop])},current),
    head(vals),
    tail(vals)

    const groupSumBy = curry((groupOn,sumOn,vals)=>
    values(map(sumBy(sumOn))(groupBy(prop(groupOn),vals)))


    groupSumBy('title','age',people)

    或者,如果我想要更简洁一点,我可能会切换到:

      const sumBy = prop =>提升(
    reduce((current,val)=> evolve({[prop]:add(val [prop])},current)
    ))(head,tail)

    请注意 sumBy 是相对可重复使用的。它并不完美,因为它会在空列表中失败。但在我们的例子中,我们知道groupBy的输出永远不会为密钥创建这样的空列表。任何在空列表中没有失败的版本都需要一种方法来提供默认情况。它只是变得丑陋。



    你可以在 Ramda REPL



    您可以使用 groupSumBy 版本/ docs / #piperel =nofollow noreferrer> pipe 撰写 如果您愿意先使用 groupOn sumOn 的值,然后用值调用结果函数,也就是说,如果调用看起来像这样:

      groupSumBy('title','age')(people)
    //或更可能:
    const foo = groupSumBy('title',age)
    FOO(PEO ple)

    但我把它作为读者的练习。


    I need help transforming an array of objects using ramda; I'd like to

    1. group by a specified property
    2. sum another property on the resulting set

    given an array like this:

    var arr = [
      {
        title: "scotty",
        age: 22,
        score: 54,
        hobby: "debugging"
    
      },  {
        title: "scotty",
        age: 22,
        score: 19,
        hobby: "debugging"
      }
      ,  {
        title: "gabriel",
        age: 40,
        score: 1000
      }
    ];
    

    if I want to group by title and sum on age it should return the following summary of values

    var arr = [
      {
        title: "scotty",
        age: 44,
        hobby: "debugging",
      }
      ,  {
        title: "gabriel",
        age: 40,
        score: 1000
      }
    ];
    

    when the unspecified property's differ in value they should be omitted, but if unspecified property's are the same in value it should remain in the final result.

    ** My Solution **

        /*
     * [Student]
     */
    var arr = [
      {
        title: "scotty",
        age: 22,
        score: 54,
        hobby: "debugging"
    
      },  {
        title: "scotty",
        age: 22,
        score: 19,
        hobby: "debugging"
      }
      ,  {
        title: "gabriel",
        age: 40,
        score: 1000
      }
    ];
    
    
    /*
     * String -> [[Student]] -> [Student]
     */
    var sumOnProperty = function(property, v){
      var sum = (x,y) => x[property] + y[property];
      var new_array = [];
       v.forEach(arr => {
         if(arr.length > 1){
            arr[0]["age"] = arr.reduce(sum)
            new_array.push(arr[0]);
         } else {
           if(arr.length != 0){
            new_array.push(arr[0]);
           }
         }
       })
      return new_array;
    }
    
    /*
     * String -> String -> [Student] -> [Student]
     */
    var groupsumBy = function(groupproperty, sumproperty, arr){ 
    
           // create grouping
           var grouping = R.groupBy(R.prop(groupproperty), arr)
    
           // convert grouping object to array 
           var result1 = R.valuesIn(grouping);
    
           // sum each grouping and flatten 2d array
           var result2 = sumOnProperty(sumproperty, result1);
    
           return result2;
    }
    
    
    groupsumBy("title","age",arr);
    

    解决方案

    To fix your groupBy problem you need to see that groupBy takes a key-generation function function and not a binary predicate.

    So, for instance,

    const byTitle = R.groupBy(R.prop('title'));
    

    This should get you through your current block. If you need help with the summation, let me know.

    Update:

    You asked for my approach. It does differ from yours a fair bit. I would probably do something like this:

    const sumBy = prop => vals => reduce(
      (current, val) => evolve({[prop]: add(val[prop])}, current),
      head(vals),
      tail(vals)
    )
    const groupSumBy = curry((groupOn, sumOn, vals) => 
      values(map(sumBy(sumOn))(groupBy(prop(groupOn), vals)))
    )
    
    groupSumBy('title', 'age', people)
    

    Or if I wanted it a little more concise, I might switch to:

    const sumBy = prop => lift(
      reduce((current, val) => evolve({[prop]: add(val[prop])}, current)
    ))(head, tail)
    

    Note that sumBy is relatively reusable. It's not perfect, because it would fail on an empty list. But in our case, we know that the output of groupBy will never create such an empty list for a key. And any version which didn't fail on an empty list would need a way to supply the default case. It simply gets ugly.

    You can see this in action on the Ramda REPL.

    You could probably make a more easily readable version of groupSumBy using pipe or compose if you were willing to call first with the groupOn and sumOn values, then call the resulting function with the values, that is, if the invocation looked like this:

    groupSumBy('title', 'age')(people)
    // or more likely:
    const foo = groupSumBy('title', age)
    foo(people)
    

    But I leave that as an exercise for the reader.

    这篇关于使用ramda group by属性和sum指定属性的结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆