0

I am trying to group my data by 2 fields MessageGroupId and FlowId

(But I want generalized way , in case I have to group more than 2 field )

My Data

 [
  {
    "Id": 46489,
    "Message": "Hi",
    "MessageGroupId": 46488,
    "FlowId": 99
  },
  {
    "Id": 46492,
    "Message": "Hi User",
    "MessageGroupId": 46490,
    "FlowId": 100
  },
  {
    "Id": 46494,
    "Message": "Loan",
    "MessageGroupId": 46490,
    "FlowId": 101
  },
  {
    "Id": 46496,
    "Message": "Call",
    "MessageGroupId": 46490,
    "FlowId": 101
  }
]

Desired Output

[
  {
    "MessageGroupId": 46488,
    "FlowId": 99,
    "values": [
      {
        "Id": 46489,
        "Message": "Hi",
        "MessageGroupId": 46488,
        "FlowId": 99
      }
    ]
  },
  {
    "MessageGroupId": 46490,
    "FlowId": 100,
    "values": [
      {
        "Id": 46492,
        "Message": "Hi User",
        "MessageGroupId": 46490,
        "FlowId": 100
      }
    ]
  },
  {
    "MessageGroupId": 46490,
    "FlowId": 101,
    "values": [
      {
        "Id": 46494,
        "Message": "Loan",
        "FlowId": 101,
        "MessageGroupId": 46490
      },
      {
        "Id": 46496,
        "Message": "Call",
        "FlowId": 101,
        "MessageGroupId": 46490
      }
    ]
  }
]

I know about d3.nest function, but when I try to use it with multiple key

var nested_data = d3.nest()
.key(function(d) { return d.MessageGroupId; })
.key(function(d) { return d.FlowId; })
.entries(conversationData.Messages);

values are nested in each other

    [
  {
    "key": "46488",
    "values": [
      {
        "key": "99",
        "values": [
          {
            "Id": 46489,
            "Message": "Hi",
            "MessageGroupId": 46488,
            "FlowId": 99
          }
        ]
      }
    ]
  },
  {
    "key": "46490",
    "values": [
      {
        "key": "100",
        "values": [
          {
            "Id": 46492,
            "Message": "Hi User",
            "MessageGroupId": 46490,
            "FlowId": 100
          }
        ]
      },
      {
        "key": "101",
        "values": [
          {
            "Id": 46494,
            "Message": "Loan",
            "MessageGroupId": 46490,
            "FlowId": 101
          },
          {
            "Id": 46496,
            "Message": "Call",
            "MessageGroupId": 46490,
            "FlowId": 101
          }
        ]
      }
    ]
  }
]

How can I achieve desired output?

var data = [
      {
        "Id": 46489,
        "Message": "Hi",
        "MessageGroupId": 46488,
        "FlowId": 99
      },
      {
        "Id": 46492,
        "Message": "Hi User",
        "MessageGroupId": 46490,
        "FlowId": 100
      },
      {
        "Id": 46494,
        "Message": "Loan",
        "MessageGroupId": 46490,
        "FlowId": 101
      },
      {
        "Id": 46496,
        "Message": "Call",
        "MessageGroupId": 46490,
        "FlowId": 101
      }
    ]
    
    
 var nested_data = d3.nest()
    .key(function(d) { return d.MessageGroupId; })
    .key(function(d) { return d.FlowId; })
    .entries(data);

console.log(nested_data);
    
    
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

2
  • Write a function which converts d3.nest function data into your own required format. Commented May 15, 2017 at 10:04
  • how? I want generallized way of doing this, not just for 2 property Commented May 16, 2017 at 8:15

1 Answer 1

2

Implemented it myself, using native javascript

Usage

arr.groupBy(['MessageGroupId','FlowId'])

Source

Array.prototype.groupBy = function (props) {
   var arr = this;
   var partialResult = {};

   arr.forEach(el=>{

       var grpObj = {};

       props.forEach(prop=>{
             grpObj[prop] = el[prop]
       });

       var key = JSON.stringify(grpObj);

       if(!partialResult[key]) partialResult[key] = [];

       partialResult[key].push(el);

   });

   var finalResult = Object.keys(partialResult).map(key=>{
      var keyObj = JSON.parse(key);
      keyObj.values = partialResult[key];
      return keyObj;
   })

   return finalResult;
}

Snippet

var arr = [{ "Id": 46489,
    "Message": "Hi",
    "MessageGroupId": 46488,
    "FlowId": 99
  },
  {
    "Id": 46492,
    "Message": "Hi User",
    "MessageGroupId": 46490,
    "FlowId": 100
  },
  {
    "Id": 46494,
    "Message": "Loan",
    "MessageGroupId": 46490,
    "FlowId": 101
  },
  {
    "Id": 46496,
    "Message": "Call",
    "MessageGroupId": 46490,
    "FlowId": 101
  }
]

Array.prototype.groupBy = function (props) {
   var arr = this;
   var partialResult = {};
   
   arr.forEach(el=>{
   
       var grpObj = {};
       
       props.forEach(prop=>{
             grpObj[prop] = el[prop]
       });
       
       var key = JSON.stringify(grpObj);
       
       if(!partialResult[key]) partialResult[key] = [];
       
       partialResult[key].push(el);
       
   });
   
   var finalResult = Object.keys(partialResult).map(key=>{
      var keyObj = JSON.parse(key);
      keyObj.values = partialResult[key];
      return keyObj;
   })
   
   return finalResult;
}


console.log(arr.groupBy(['MessageGroupId','FlowId']))

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.