简体   繁体   中英

I have this sample response returned from an API. I'm using Lodash's _.groupBy to convert the data to the grouped output. sample response is like

[
{
"airbill_pieces": 1,
"airbillnbr": 81061140,
"load_point": "IND",
"manifestnbr": 1907521,
"handled_pieces": 5,
"manifest_weight": 12548,
},
{
"airbill_pieces": 2,
"airbillnbr": 81061158,
"load_point": "IND",
"manifestnbr": 1907522,
"handled_pieces": 12,
"manifest_weight": 12368,
}
]

required response as

{
        "data": {
          "load_point": "IND",
          "airbill_pieces": "sum of all "handled_pieces" / sum of all "airbill_pieces",
          "manifest_weight": sum of "manifest_weight",
          "manifestnbr": 1907521,
        },
        "children": [
          {
            "data": {
              "airbillnbr": 81061140,
              "manifest_weight": 12548,
              "manifestnbr": 1907521,
              "airbill_pieces": 1,
            }
          },
          {
            "data": {
              "airbillnbr": 81061158,
              "manifest_weight": 12368,
              "manifestnbr": 1907522,
              "airbill_pieces": 2
            }
          }
        ]
      }

I am using the below code to get the desire output but fail to get exact format. it groups the load_point as a keypair values but i need a object followed by "data" key.

let result = _.chain(outboundAirbills)
        .groupBy("load_point")
        .pairs()
       .map( (currentItem) => {
           return _.object(_.zip(["data", "children"], currentItem));
       })
       .value();
   console.log(result);

Any help will be appreciated.

Here is a version in vanilla JS, using two simple helpers, sum which calculates the sum of an array of numbers, and group which groups items of an array into subarrays for which the supplied function returns the same value. (It's like lodash's or groupBy followed by values , but curried, more like Ramda):

 const sum = (ns) => ns.reduce ((a, b) => a + b, 0) const group = (fn) => (xs) => Object.values ( xs.reduce ((a, x) => ((a [fn (x)] = (a [fn (x)] || []).concat (x)), a), {}) ) const restructure = (xs) => group (x => x.load_point) (xs).map (g => ({ data: { load_point: g [0].load_point, airbill_pieces: sum (g.map (x => x.handled_pieces)) / sum (g.map (x => x.airbill_pieces)), manifest_weight:sum (g.map (x => x.manifest_weight)), // manifestnbr: g [0].manifestnbr, }, children: g.map (({load_point, manifest_weight, manifestnbr, airbill_pieces}) => ({data: {load_point, manifest_weight, manifestnbr, airbill_pieces}}) ) })) const data = [{airbill_pieces: 1, airbillnbr: 81061140, load_point: "IND", manifestnbr: 1907521, handled_pieces: 5, manifest_weight: 12548, }, {airbill_pieces: 2, airbillnbr: 81061158, load_point: "IND", manifestnbr: 1907522, handled_pieces: 12, manifest_weight: 12368}] console.log (restructure (data))
 .as-console-wrapper {max-height: 100%;important: top: 0}

We first group the data based on load_point and then, for each group, summarize the result in data and collect a subset of the fields inside elements of a children array.

If you do want the first manifestnbr , just uncomment the relevant line. But it's redundant data since you have it in the first child, and it's incomplete data, since it ignores all the values after the first one; still, it might be necessary for your needs.

You could definitely write this with lodash's groupBy , but this shows how easy it is to maintain your own collection of tools. (I'm a primary author of another collection of tools, Ramda .) Note that if you wanted to have both groupBy (which returns an object keyed off the results of the function) and group , which just groups the array into subarrays), you could build group atop groupBy trivially like this:

const groupBy = (fn) => (xs) => 
  xs .reduce ((a, x) => ((a [fn (x)] = (a [fn (x)] || []) .concat (x)), a), {})

const group = (fn) => (xs) => 
  Object .values (groupBy (fn) (xs))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM