0

I'm trying to filter this objects array and keep the original one aside.

{"departments":
 [
  {
    “name": “AAA",
    “selected”: true,            
    "courses": [
        {
            "name": “course1",
            “selected”: true,
            “titles”: 
            [{
              "name": “title1",
              “selected”: true
             },
             {
             "name": “title2",
             “selected”: false
            }]
         },
         {
            "name": “course2",
            “selected”: false,
            “titles”: 
            [{
              "name": “title1",
              “selected”: false
             }]   
          }
    ]
 },
 {
    “name": “BBB",
    “selected”: false,
    "courses": [{...}]

 {...}    
 ]
}

I want to find all the selected departments, courses and titles. And it should be in the same format. I tried with below code, but it change original data. I want to keep that aside too.

const depts = departments.filter((dept: any) => {
    if (dept.selected) {
      dept.courses = dept.courses.filter((course: any) => {
        if (course.selected) {
          if (course.titles) {
            course.titles = course.titles.filter(({selected}: any) => selected);
          }
          return true;
        }
        return false;
      });
      return true;
    }
    return false;
  });

What would be considered the best solution in this case?

4 Answers 4

1

Shorter alternative can be to use the JSON.parse reviver parameter :

var arr = [{ name: "AAA", selected: true, courses: [{name: "course1", selected: true, titles: [{ name: "title1", selected: true }, { name: "title1", selected: false }]}, { name: "course2", selected: false, titles: [{ name: "title1", selected: false }]}]}]

var result = JSON.parse(JSON.stringify(arr), (k, v) => v.map ? v.filter(x => x.selected) : v)

console.log( result )

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

Comments

1

your filtering logic seems to be correct. only problem is that code changes original array. in order to overcome this problem just create a deep clone of original array and run filtering logic on it

  filterArray() {
    const clone = JSON.parse(JSON.stringify(this.departments));
    const depts = clone.filter((dept: any) => {
      if (dept.selected) {
        dept.courses = dept.courses.filter((course: any) => {
          if (course.selected) {
            if (course.titles) {
              course.titles = course.titles.filter(({ selected }: any) => selected);
            }
            return true;
          }
          return false;
        });
        return true;
      }
      return false;
    });

    console.log(depts);
  }

here is a demo https://stackblitz.com/edit/angular-xx1kp4

Comments

0

const filterSelected = obj => {
  return {
    ...obj,
    departments: obj.departments.map(dep => {
      return {
        ...dep,
        courses: dep.courses.map(course => {
          return {
            ...course,
            titles: course.titles.filter(title => title.selected),
          };
        }).filter(course => course.selected),
      };
    }).filter(dep => dep.selected),
  };
}

const all = {
 departments: [
  {
   name: "AAA",
   selected: true,            
   courses: [
    {
     name: "course1",
     selected: true,
     titles: [
      {
       name: "title1",
       selected: true
      }, {
       name: "title1",
       selected: false
      }
     ]
    }, {
     name: "course2",
     selected: false,
     titles: [
      {
       name: "title1",
       selected: false
      }
     ]
    },
   ]
  }
 ]
};

console.log(filterSelected(all));

Comments

0

I don't know if you prefer an API false. Here is my tip:

You can to use an API Json Server.

Install JSON Server

npm install -g json-server

Create a db.json file with some data

{
  "posts": [
    { "id": 1, "title": "json-server", "author": "typicode" }
  ],
  "comments": [
    { "id": 1, "body": "some comment", "postId": 1 }
  ],
  "profile": { "name": "typicode" }
}

Start JSON Server

json-server --watch db.json

Now if you go to http://localhost:3000/posts/1, you'll get

{ "id": 1, "title": "json-server", "author": "typicode" }

you can search your array of objects using various shapes and it will come filtered. More about the API here: https://github.com/typicode/json-server

(Use a filter to do your searches on the Angular, it will bring you right what you need, use a method inside your component)

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.