Home > other >  Filtering Complex JSON Data
Filtering Complex JSON Data

Time:11-27

I would like to filter data by taking the value of serial_number or name as input in the JSON given below. However, I have no idea of figuring out how to look for the data through the entire JSON given the complexity of it. For example, if query.serial_number is 0018, then it should return all the data in that object along with the serial_number.

I had tried a lot of things combining on my own combining the filter and map methods which definitely did not help out. Also, if searching by name, would it be possible to return multiple results if the same name occured more than once in the JSON?

Below is the JSON data:

[
    {
        "district": "Kolkata",
        "ward_no": [
            {
                "ward": "6",
                "grievance": [
                    {
                        "serial_number": "0001",
                        "name" : "Mr.A"
                    },
                    {
                        "serial_number": "0002",
                        "name" : "Mr.B"
                    }
                ],
                "general": [
                    {
                        "serial_number": "0003",
                        "name" : "Mr.C"
                    },
                    {
                        "serial_number": "0004",
                        "name" : "Mr.D"
                    }
                ]
            },
            {
                "ward": "7",
                "grievance": [
                    {
                        "serial_number": "0005",
                        "name" : "Mr.E"
                    },
                    {
                        "serial_number": "0006",
                        "name" : "Mr.F"
                    }
                ],
                "general": [
                    {
                        "serial_number": "0007",
                        "name" : "Mr.G"
                    },
                    {
                        "serial_number": "0008",
                        "name" : "Mr.H"
                    }
                ]
            }
        ]
    },
    {
        "district": "Hooghly",
        "ward_no": [
            {
                "ward": "8",
                "grievance": [
                    {
                        "serial_number": "0009",
                        "name" : "Mr.I"
                    },
                    {
                        "serial_number": "0010",
                        "name" : "Mr.J"
                    }
                ],
                "general": [
                    {
                        "serial_number": "0011",
                        "name" : "Mr.K"
                    },
                    {
                        "serial_number": "0012",
                        "name" : "Mr.L"
                    }
                ]
            },
            {
                "ward": "9",
                "grievance": [
                    {
                        "serial_number": "0013",
                        "name" : "Mr.M"
                    },
                    {
                        "serial_number": "0014",
                        "name" : "Mr.N"
                    }
                ],
                "general": [
                    {
                        "serial_number": "0015",
                        "name" : "Mr.O"
                    },
                    {
                        "serial_number": "0018",
                        "name" : "Bruno Fernandes"
                    }
                ]
            }
        ]
    }
]

I intend to take the inputs this way:

var query = {
   name: "Bruno Fernandes"
};

or when in need of searching by serial_number:

var query = {
   serial_number: "18"
};

CodePudding user response:

Below, I made interfaces for the data, so we can easily see how it is layed out.

Here's a link to a Codesandbox, where you can try the code yourself.

interface Hospital {
  district: string;
  ward_no: Ward[];
}
interface Ward {
  ward: string;
  grievance: Patient[];
  general: Patient[]
}
interface Patient {
  serial_number: string;
  name: string;
}

If we want to get them by serial_number, then we can use three loops for each array.

function getById(id:number){
  for (const hospital of json) {
    for (const ward of hospital.ward_no) {
      for (const patient of ward.general) {
        if (patient.serial_number === id) return patient;
      }
      for (const patient of ward.grievance) {
        if (patient.serial_number === id) return patient;
      }
    }
  }
  return null;
}

We can make it more flexible, if we use keyof so we can choose the property we want to match.

function getPatientBy(prop: keyof Patient, value: string) {
  for (const hospital of json) {
    for (const ward of hospital.ward_no) {
      for (const patient of ward.general) {
        if (patient[prop] === value) return patient;
      }
      for (const patient of ward.grievance) {
        if (patient[prop] === value) return patient;
      }
    }
  }
  return null;
}

This will now give use auto complete on the properties of Patient.

You can then make similar functions for Ward and Hospital.

CodePudding user response:

You need to map them. Will give an example then you can tweak as you need

const data = // YOUR ARRAY
var query = {
   serial_number: "18"
};

{data.filter(item => item.ward_no.grievance.serial_number.includes(query) || item.ward_no.general.serial_number.includes(query)).map((value, index) => {
return(
   <p>{value.ward_no.grievance.serial_number || value.ward_no.general.serial_number}</p>
)}

you can also set this up to search by the name if you need help let me know and I can post a revised answer if this option works for you :)

CodePudding user response:

For javascript, there is an infinity of libraries for manipulating collections and objects, but I recommend

npm i @arcaela/eloquent
  • Related