简体   繁体   中英

groupBy or partitioning object with multiple keys with lodash

I have an array of packets so that each packet has source IP and destination IP. I want to find the best way to divide the array so that in the end I'll get a dictionary whose keys are IP and their value is all the packets sent from or to that IP.

For example, if this is my array:

let packets = [ {sourceIp:127.0.0.1, destIp:127.0.0.2}, 
                {sourceIp:127.0.0.2, destIp:127.0.0.3},
                {sourceIp:127.0.0.3, destIp:127.0.0.1},
                {sourceIp:127.0.0.2, destIp:127.0.0.1}]

I'm looking for a way to get-

result = { 127.0.0.1: [{sourceIp:127.0.0.1, destIp:127.0.0.2},{sourceIp:127.0.0.3, destIp:127.0.0.1},
                       {sourceIp:127.0.0.2, destIp:127.0.0.1}],
           127.0.0.2: [{sourceIp:127.0.0.1, destIp:127.0.0.2},{sourceIp:127.0.0.2, destIp:127.0.0.3},
                       {sourceIp:127.0.0.2, destIp:127.0.0.1}],
           127.0.0.3: [{sourceIp:127.0.0.2, destIp:127.0.0.3},{sourceIp:127.0.0.3, destIp:127.0.0.1}]
         }

Thank you:-)

First of all json array objects data type should be in string.

Then use lodash in _.groupBy()

 const packets = [{ sourceIp: "127.0 .0 .1", destIp: "127.0 .0 .2" }, { sourceIp: "127.0 .0 .2", destIp: "127.0 .0 .3" }, { sourceIp: "127.0 .0 .3", destIp: "127.0 .0 .1" }, { sourceIp: "127.0 .0 .2", destIp: "127.0 .0 .1" } ] const splittedData = _.groupBy(packets, 'sourceIp'); console.clear(); console.log(splittedData);
 <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>

Step 1: Create both perspectives

Presuming sourceIp & destinationIp are always different (which seems reasonable), I would first duplicate the array so that you have 1 with source as "key", and 1 with destination as "key":

const packetsBySource = packets.map(({ sourceIp, destIp }) => ({ key: sourceIp, sourceIp, destIp }))
const packetsByDest = packets.map(({ sourceIp, destIp }) => ({ key: destIp, sourceIp, destIp }))

Step 2: Merge & groupBy

Then I would merge these together, and do a groupBy:

import groupBy from 'lodash/groupBy'

const both = [...packetsBySource, ...packetsByDest]
const keyed = groupBy(both, 'key')

Notes

  • Your objects will still have the extra key property; if this is a problem you will need: const keyedClean = mapValues(keyed, (packets) => packets.map(({ sourceIp, destIp }) => ({ sourceIp, destIp })))
  • If you have a really big input array then performance might become important; it might be faster to use groupBy twice on the original array, and then merge the 2 result objects (I don't know off-hand a quick way to merge array properties)

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