2

I have a huge set of JSON data which I consider to be pretty complex when it comes to filtering data out of it. The idea is to take inputs from the user from the District, Ward No, and Categories dropdowns and use those to filter out the data i.e (grievances, general, urgent, and service), and display their properties in the table below. So like let's say if the selected value from the dropdown is "Grievances", it should show all the properties from the grievances array in the table. I have tried using the filter method by taking hardcoded inputs to see if the console would print anything or not but apparently it doesn't. I don't think I'll be able to move any further without support on this. Below, you will find a snippet of the dropdowns, the JSON and the code that I tried for testing.

enter image description here

P.S Please ignore the data on the table as it is only hardcoded. The picture is only to give you a basic idea of what I intend to do once I get the correct resolution for the code I have written for testing.

JSON(Please note that every district has 3 ward in total. For example, in this case, the ward is 6 which has the following arrays namely "grievance", "general", "urgent", "services")

[
    {
        "district": "Kolkata",    //There are two other district values as well
        "ward_no": [
            {
                "ward": "6",     
                "grievance": [
                    {
                        "serial_number": "0001",
                        "name": "Siddhartha Chatterjee"
                    },
                    {
                        "serial_number": "0002",
                        "name": "Sajujjo Ghosh"
                    }
                ],
                "general": [
                    {
                        "serial_number": "0003",
                        "name": "Dr. Partha Pratim Paul"
                    },
                    {
                        "serial_number": "0004",
                        "name": "Dr. Partha Pratim Paul"
                    }
                ],
                "urgent": [
                    {
                        "serial_number": "0005",
                        "name": "Ritwick Banerjee"
                    },
                    {
                        "serial_number": "0006",
                        "name": "Soumadip Banerjee"
                    }
                ],
                "services": [
                    {
                        "serial_number": "0007",
                        "name": "Tanajeet Biswas"
                    },
                    {
                        "serial_number": "0008",
                        "name": "Durba Chatterjee"
                    }
                ]
            }
        ]
    }
]

The code(The query object is to store the values received from the dropdowns dynamically. This right now is hardcoded and once I have the solution, I believe I'll be able to manage the rest)

const Screen = () => {
    var wardNo = dummyData.map(value => value.ward_no.map(value => value.ward));
    console.log(`Ward Filter: ${wardNo}`);    //To check if all the values of ward are getting displayed
    var categorySelected = dummyData.map(value => value.types.map(value => value.category));
    console.log(`category ${category}`);     //To check if all the values of category are getting displayed
    var query = {                            
        district : "Kolkata",
        ward : "6",
        category : "Grievances"
    };
    var filteredData = dummyData.filter(value => (value.district === query.district && wardNo === query.ward && categorySelected === query.category));  //The logic I used
    console.log(`filteredData ${filteredData.length}`);    //This returns 0 stating no data got filtered at all
       
    return(
        <div>
            
        </div>
    );
}

1 Answer 1

3

First of all, I'd say your JSON data is purely structured. I mean ward_no. You have categories with the dynamic name and makes it harder to filter out data while the name ward is also there (which can be a category name as well). As a suggestion, if you have an option to modify that part like this below then consider changing it.

  {
    district: 'Kolkata',
    ward_no: [
      {
        ward: '6',
        category: 'grievance',
        data: [
          {
            serial_number: '0001',
            name: 'Siddhartha Chatterjee',
          },
          {
            serial_number: '0002',
            name: 'Sajujjo Ghosh',
          },
        ],
      },
    ],
  },

I tried to make a filter function for you based on the parameters you have defined (ward, district, category).

It filters out data based on AND comparison for example when ward, category are passed both have to match.

// Your original data but minified
const data = [{"district":"Kolkata","ward_no":[{"ward":"6","grievance":[{"serial_number":"0001","name":"Siddhartha Chatterjee"},{"serial_number":"0002","name":"Sajujjo Ghosh"}],"general":[{"serial_number":"0003","name":"Dr. Partha Pratim Paul"},{"serial_number":"0004","name":"Dr. Partha Pratim Paul"}],"urgent":[{"serial_number":"0005","name":"Ritwick Banerjee"},{"serial_number":"0006","name":"Soumadip Banerjee"}],"services":[{"serial_number":"0007","name":"Tanajeet Biswas"},{"serial_number":"0008","name":"Durba Chatterjee"}]}]}];

/**
 * @description This function is used to filter the data based on the params
 * @param {{
 *   district: string,
 *   ward: string,
 *   category: string,
 * }} filterData
 */
function myFilter(filterData) {
  return data.filter((item) => {
    const filter = {
      byDistrict: true,
      byWard: true,
      byCategory: true,
    };
    if (filterData.district) filter.byDistrict = item.district === filterData.district;
    // Even if one ward_no.ward matches the value it's true
    if (filterData.ward) filter.byWard = item.ward_no.some((wards) => wards.ward === filterData.ward); 
    if (filterData.category)
      filter.byCategory = item.ward_no.some((wards) =>
        Object.keys(wards).some((categoryName) => categoryName !== 'ward' && categoryName === filterData.category));

    return filter.byDistrict && filter.byWard && filter.byCategory;
  });
}

console.log('1st filter', myFilter({ district: 'Kolkata', ward: '6', category: 'grievance' }));
// The second wont work as the district doesn't match
console.log('2nd filter', myFilter({ district: 'Kolkata-wrong', ward: '6', category: 'grievance' }));
// If you omit the district it will ignore its value and look for only ward and category
console.log('3rd filter', myFilter({ ward: '6', category: 'grievance' }));
// Same applies here
console.log('4th filter', myFilter({ category: 'grievance' }));

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

4 Comments

Hi mate. I'm a little confused about what you suggested earlier about considering changing the structure of my JSON, yet it appears that you have applied your logic to the data that I originally created. Am I to understand that your suggestion for changing the structure was optional? And just to add, Thanks a lot for the solution
Hi 👋. . Yes, my code works with your original data no need to change anything. I just suggested as an improvement to change the structure as I explained above. However, if you change the structure you need to change filtering logic as well. Changes will be required in category filtering where you dont have to get Object.keys since category name will be already there for comparison.
Just one more thing though, how do you suppose I can filter the data when either "Hooghly" or "Malda" is taken as the input in console.log('2nd filter', myFilter({ district: 'Kolkata-wrong', ward: '6', category: 'grievance' }));
Do you want to filter based on multiple value match? In such case you can make the the function parameter for example district as an array and in district filter func change item.district === filterData.district to filterData.district.includes(item.district). Call the function like this myFilter({ district: ['Kolkata', 'SomethingElse'] })

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.