skip to Main Content

I have a list of subjects and need to filter it based on the filter selection

let subjects = [
    {
        "id": "course 1",
        "title": "course 1",
        "area": ["red"," blue"],
        "mode": "offline",
        "available": "full-time | part-time",
    },
    {
        "id": "course 2",
        "title": "course 3",
        "area": ["red"],
        "mode": "online",
        "available": "part-time",
    },
    {
        "id": "course 2",
        "title": "course 3",
        "area": ["blue", "green"],
        "mode": "offline",
        "available": "full-time | part-time",
    },
]

There are 3 filters(area, mode, available) where the user can select multiple options from each filter

For example, after user selection my filter object looks like (it can be empty if none of the options are chosen from filters, here I have not chosen any options from filter2)

let filters = { filter1: ["red", "green"], filter2: "" , filter3: ["full-time"]}

Expected output

Based on the filters selected, I need to display the subjects that has

  1. subjects.area as red or green or both
  2. subjects.available as full-time
let subjects = [
    {
        "id": "course 1",
        "title": "course 1",
        "area": ["red"," blue"],
        "mode": "offline",
        "available": "full-time | part-time",
    },
    {
        "id": "course 2",
        "title": "course 3",
        "area": ["blue", "green"],
        "mode": "offline",
        "available": "full-time | part-time",
    },
]

Things I tried

  1. I tried using filter() and includes
const results = subjects.filter(function(s){
                  return s.includes(filters)
               )};
  1. I tried converting the filter object to an array with the selected values eg;let filters = ["red","green","full-time"] and used filter() and includes , but no luck

2

Answers


  1. If you habe an object with same named properties, you could take a dynamic approach, by converting all items to arrays and check against.

    const 
        subjects = [{ id: "course 1", title: "course 1", area: ["red"," blue"], mode: "offline", available: ["full-time", "part-time"] }, { id: "course 2", title: "course 3", area: ["red"], mode: "online", available: "part-time" }, { id: "course 2", title: "course 3", area: ["blue", "green"], mode: "offline", available: ["full-time", "part-time"] }],
        filters = { area: ["red", "green"], mode: "" , available: ["full-time"] },
        constraints = Object
            .entries(filters)
            .filter(([, v]) => v !== '')
            .map(([k, v]) => [k, [].concat(v)]),
        result = subjects.filter(o => constraints.every(([key, value]) => []
            .concat(o[key])
            .some(v => value.includes(v))
        ));
    
    console.log(result);
    Login or Signup to reply.
  2. let subjects = [
        {
            "id": "course 1",
            "title": "course 1",
            "area": ["red"," blue"],
            "mode": "offline",
            "available": "full-time | part-time",
        },
        {
            "id": "course 2",
            "title": "course 3",
            "area": ["red"],
            "mode": "online",
            "available": "part-time",
        },
        {
            "id": "course 2",
            "title": "course 3",
            "area": ["blue", "green"],
            "mode": "offline",
            "available": "full-time | part-time",
        },
    ]
    
    let filters = { filter1: ["red", "green"], filter2: "" , filter3: ["full-time"]}
    
    const filtered = subjects.filter(
        subject => subject.area.some(area => filters.filter1.includes(area)) 
        && (!filters.filter2 || filters.filter2 === subject.mode) 
        && subject.available.split(/s*|s*/g).some(available => filters.filter3.includes(available))
    )
    
    
    console.log(filtered)
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search