Nitish Phanse
Nitish Phanse

Reputation: 562

converting flat json to nested

I have the following JSON

{
  "rate_cards": [
    {
      "doctor_id": "xxxxxx",
      "doctor_name": "Dr. Dre",
      "practice_id": "xxxxx",
      "is_owner": 0,
      "policy_id": 1,
      "policy_name": "GOLD Super Gold",
      "payor_id": 1,
      "payor_name": "AMEX",
      "payor_registration_number": "AMEX123",
      "payor_contact_email": "[email protected]",
      "payor_support_number": "PHONE",
      "payor_logo_url": "url",
      "doctors_policies_ratecards_id": 1,
      "ratecard_activation_status": "Pending",
      "ratecard_id": 1,
      "ratecard_validity": "2017-04-17T13:16:58.000Z",
      "ratecard_details": "{'Root Canal': 300, 'Consultation': 500}",
      "onboarded_status": "Available"
    },
    {
      "doctor_id": xxxxxx,
      "doctor_name": "<NAME>",
      "practice_id": "xxxxxx",
      "is_owner": 0,
      "policy_id": 2,
      "policy_name": "GOLD Super Gold",
      "payor_id": 1,
      "payor_name": "AMEX",
      "payor_registration_number": "AMEX",
      "payor_contact_email": "[email protected]",
      "payor_support_number": "<PHONE>",
      "payor_logo_url": "url",
      "doctors_policies_ratecards_id": 2,
      "ratecard_activation_status": "Pending",
      "ratecard_id": 1,
      "ratecard_validity": "2017-04-17T13:16:58.000Z",
      "ratecard_details": "{'Root Canal': 300, 'Consultation': 500}",
      "onboarded_status": "Available"
    }
  ]
}

and i want to convert it to

{
  "payors": [
      {
          "payor_id": 1,
          "payor_name": "AMEX",
          "payor_registration_number": "AMEX",
          "payor_contact_email": "[email protected]",
          "payor_support_number": "<PHONE>",
          "payor_logo_url": "url",
          "data": [
              {
                  "doctor_id":xxxxx,
                  "doctor_name": "Dr. Dre",
                  "practice_id": xxxxxx,
                  "is_owner": 0,
                  "policy_id": 1,
                  "policy_name": "GOLD Super Gold",
                  "doctors_policies_ratecards_id": 1,
                  "ratecard_activation_status": "Pending",
                  "ratecard_id": 1,
                  "ratecard_validity": "2017-04-17T13:16:58.000Z",
                  "ratecard_details": "{'Root Canal': 300, 'Consultation': 500}",
                  "onboarded_status": "Available"
              }, 
              {
                  "doctor_id": xxxxxx,
                  "doctor_name": "name",
                  "practice_id": xxxxxxx,
                  "is_owner": 0,
                  "policy_id": 2,
                  "policy_name": "GOLD Super Gold",
                  "doctors_policies_ratecards_id": 2,
                  "ratecard_activation_status": "Pending",
                  "ratecard_id": 1,
                  "ratecard_validity": "2017-04-17T13:16:58.000Z",
                  "ratecard_details": "{'Root Canal': 300, 'Consultation': 500}",
                  "onboarded_status": "Available"
              }
          ]
      }
  ]
}

Basically i group by based on the payor_name and that becomes my primary reference nesting the structure. I tried using lodash groupBy and transform but was unable to achieve the above structure. Any sort of help on what i can do will be greatfull.

Upvotes: 1

Views: 753

Answers (3)

Rodrigo5244
Rodrigo5244

Reputation: 5525

I iterate over rate_cards adding payors to my dictionary indexed by id. For each payor I add the rest of the object to the data array.

After that loop I convert my dictionary into an array and print the result.

const input = {
  "rate_cards": [{
      "doctor_id": "xxxxxx",
      "doctor_name": "Dr. Dre",
      "practice_id": "xxxxx",
      "is_owner": 0,
      "policy_id": 1,
      "policy_name": "GOLD Super Gold",
      "payor_id": 1,
      "payor_name": "Amex",
      "payor_registration_number": "AMEX123",
      "payor_contact_email": "[email protected]",
      "payor_support_number": "PHONE",
      "payor_logo_url": "url",
      "doctors_policies_ratecards_id": 1,
      "ratecard_activation_status": "Pending",
      "ratecard_id": 1,
      "ratecard_validity": "2017-04-17T13:16:58.000Z",
      "ratecard_details": "{'Root Canal': 300, 'Consultation': 500}",
      "onboarded_status": "Available"
    },
    {
      "doctor_id": "xxxxxx",
      "doctor_name": "<NAME>",
      "practice_id": "xxxxxx",
      "is_owner": 0,
      "policy_id": 2,
      "policy_name": "GOLD Super Gold",
      "payor_id": 1,
      "payor_name": "AMEX",
      "payor_registration_number": "AMEX",
      "payor_contact_email": "[email protected]",
      "payor_support_number": "<PHONE>",
      "payor_logo_url": "url",
      "doctors_policies_ratecards_id": 2,
      "ratecard_activation_status": "Pending",
      "ratecard_id": 1,
      "ratecard_validity": "2017-04-17T13:16:58.000Z",
      "ratecard_details": "{'Root Canal': 300, 'Consultation': 500}",
      "onboarded_status": "Available"
    }
  ]
};

const payors = new Map();

function isPayorProperty(value, key) {
  return key.indexOf('payor') === 0;
}

for (const card of input.rate_cards) {
  if (!payors.has(card.payor_id)) {
    payors.set(card.payor_id, _.assign({
      data: []
    }, _.pickBy(card, isPayorProperty)));
  }

  const payor = payors.get(card.payor_id);
  payor.data.push(_.pickBy(card, _.negate(isPayorProperty)));
}

const output = {
  "rate_cards": []
};

for (const payor of payors) {
  output.rate_cards.push(payor[1]);
}

console.log(output);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>

Upvotes: 1

Nina Scholz
Nina Scholz

Reputation: 386570

In plain Javascript, you could use a hash table as reference to the same grouping item and separate the data with lookup if the prefix payor and take the one with for grouping data and the rest for the relevant data.

var data = { rate_cards: [{ doctor_id: "xxxxxx", doctor_name: "Dr. Dre", practice_id: "xxxxx", is_owner: 0, policy_id: 1, policy_name: "GOLD Super Gold", payor_id: 1, payor_name: "AMEX", payor_registration_number: "AMEX123", payor_contact_email: "[email protected]", payor_support_number: "PHONE", payor_logo_url: "url", doctors_policies_ratecards_id: 1, ratecard_activation_status: "Pending", ratecard_id: 1, ratecard_validity: "2017-04-17T13:16:58.000Z", ratecard_details: "{'Root Canal': 300, 'Consultation': 500}", onboarded_status: "Available" }, { doctor_id: "xxxxxx", doctor_name: "<NAME>", practice_id: "xxxxxx", is_owner: 0, policy_id: 2, policy_name: "GOLD Super Gold", payor_id: 1, payor_name: "AMEX", payor_registration_number: "AMEX", payor_contact_email: "[email protected]", payor_support_number: "<PHONE>", payor_logo_url: "url", doctors_policies_ratecards_id: 2, ratecard_activation_status: "Pending", ratecard_id: 1, ratecard_validity: "2017-04-17T13:16:58.000Z", ratecard_details: "{'Root Canal': 300, 'Consultation': 500}", onboarded_status: "Available" }] },
    result = { payors: [] };

data.rate_cards.forEach(function (hash) {
    return function (o) {
        var temp = { payor: {}, data: {} };
        Object.keys(o).forEach(function (k) {
            temp[k.match(/^payor/) || 'data'][k] = o[k];
        });
        if (!hash[o.payor_name]) {
            temp.payor.data = [];
            hash[o.payor_name] = temp.payor;
            result.payors.push(hash[o.payor_name]);
        }
        hash[o.payor_name].data.push(temp.data);
    };
}(Object.create(null)));
  
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Upvotes: 0

anshulk
anshulk

Reputation: 458

You can do this via lodash (skipped some keys, handle them) -

var data = {
  "rate_cards": [
    {
      "doctor_id": "xxxxxx",
      "doctor_name": "Dr. Dre",
      "practice_id": "xxxxx",
      "is_owner": 0,
      "policy_id": 1,
      "policy_name": "GOLD Super Gold",
      "payor_id": 1,
      "payor_name": "Amex",
      "payor_registration_number": "AMEX123",
      "payor_contact_email": "[email protected]",
      "payor_support_number": "PHONE",
      "payor_logo_url": "url",
      "doctors_policies_ratecards_id": 1,
      "ratecard_activation_status": "Pending",
      "ratecard_id": 1,
      "ratecard_validity": "2017-04-17T13:16:58.000Z",
      "ratecard_details": "{'Root Canal': 300, 'Consultation': 500}",
      "onboarded_status": "Available"
    },
    {
      "doctor_id": "xxxxx",
      "doctor_name": "<NAME>",
      "practice_id": "xxxxxx",
      "is_owner": 0,
      "policy_id": 2,
      "policy_name": "GOLD Super Gold",
      "payor_id": 1,
      "payor_name": "AMEX",
      "payor_registration_number": "AMEX",
      "payor_contact_email": "[email protected]",
      "payor_support_number": "<PHONE>",
      "payor_logo_url": "url",
      "doctors_policies_ratecards_id": 2,
      "ratecard_activation_status": "Pending",
      "ratecard_id": 1,
      "ratecard_validity": "2017-04-17T13:16:58.000Z",
      "ratecard_details": "{'Root Canal': 300, 'Consultation': 500}",
      "onboarded_status": "Available"
    }
  ]
};

var newdata = _.reduce(data.rate_cards,
    function( arr, item){
      var index = _.findIndex(arr, { "payor_id" : item.payor_id});
      if(index > -1){
        arr[index].data.push(item);
      } else {
        arr.push({ "payor_id" : item.payor_id, "data" : [item] });
      }
     return arr;
    },
    []
    );
    
console.log({ "payors" : newdata});
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>

Upvotes: 1

Related Questions