Underline group and amount

Input:

const data = [
  {
    id: 'RS11',
    name: 'Road 1',
    quantity: {
      lengthVal: 50
    }
  },
  {
    id: 'RS11',
    name: 'Road 1',
    quantity: {
      lengthVal: 100
    }
  },
   {
    id: 'RS11',
    name: 'Road 2',
    quantity: {
      lengthVal: 20
    }
  }
]

Each property, except quantity, should be grouped. quantity.lengthValshould be summarized. You should also add a property count.

Expected Result:

const expected = [
  {
    id: 'RS11',
    name: 'Road 1',
    count: 2,
    summarizedLength: 150
  },
   {
    id: 'RS11',
    name: 'Road 2',
    count: 1,
    summarizedLength: 20
  }
]

This is what I tried:

const groupAndSum = (arr) => {
  return _.chain(arr)
    .groupBy((obj) => {
       // Some reduce here?
       return _.values(_.without(obj), 'quantity').join('|')
    })
    .map((val) => {
       val[0].count = val.length;
       delete val[0].quantity;
       return val[0];
    })
    .value();
}

Jsbin: https://jsbin.com/totujopume/edit?html,js,console

The data set is quite large, so performance is important.

+4
source share
1 answer

You can do this with a fairly simple native reduce () that does just one iteration through the array for the whole procedure

const res = Object.values(
  data.reduce((a, c) => {
    const key = c.id + '|' + c.name;
    const o = a[key] = a[key] || c;
    o.count            = (o.count || 0) +1;
    o.summarizedLength = (o.summarizedLength || 0) + c.quantity.lengthVal;
    delete c.quantity;
    return a;
  },{})
);

console.log(res)
.as-console-wrapper {	max-height: 100%!important;}
<script>
  const data = [{
      id: 'RS11',
      name: 'Road 1',
      quantity: {
        lengthVal: 50
      }
    },
    {
      id: 'RS11',
      name: 'Road 1',
      quantity: {
        lengthVal: 100
      }
    },
    {
      id: 'RS11',
      name: 'Road 2',
      quantity: {
        lengthVal: 20
      }
    }
  ]
</script>
Run codeHide result
+2
source

Source: https://habr.com/ru/post/1691955/


All Articles