Home > Mobile >  Could use someone's expertise with filtering my nested array by a certain value
Could use someone's expertise with filtering my nested array by a certain value

Time:03-05

I know there are a ton of "How to filter my array" questions. However, I'm still stuck.

I'm not too familiar with arrays and I'm hoping someone can help me with my particular situation.

I have an array that I'm trying to filter. I'm looking to return all data if "user.name" or "writers.name" equals "Adam". "user" will only ever have one name, while "writers" can have multiple.

    [{
     mediaId: '86699',
     user: {
       name: 'Adam',
       id: '17622'
     },
     nodeType: 'testNode',
     title: 'testTitle',
     id: '23968',
     writers: []
   },
   {
     mediaId: '90547',
     user: {
       name: 'Jake',
       id: '65936'
     },
     nodeType: 'testNode',
     title: 'testTitleTwo',
     id: '89960',
     writers: [{
         name: 'Adam',
         id: '17622'
       },
       {
         name: 'Steve',
         id: '47622'
       }]
   },
   {
     mediaId: '99662',
     user: {
       name: 'James',
       id: '22236'
     },
     nodeType: 'testNode',
     title: 'testTitleThree',
     id: '89960',
     writers: [{
       name: 'Paul',
       id: '27622'
     }]
   }
 ]

Desired output:

[{
    "mediaId": "86699",
    "user": {
      "name": "Adam",
      "id": "17622"
    },
    "nodeType": "testNode",
    "title": "testTitle",
    "id": "23968",
    "writers": []
  },
  {
    "mediaId": "90547",
    "user": {
      "name": "Jake",
      "id": "65936"
    },
    "nodeType": "testNode",
    "title": "testTitleTwo",
    "id": "89960",
    "writers": [{
        "name": "Adam",
        "id": "17622"
      },
      {
        "name": "Steve",
        "id": "45389"
      }]
  }
]

Thank you in advance!!!

CodePudding user response:

input.filter(element => element.user.name === 'Adam' || element.writers.some(writer => writer.name === 'Adam'));

CodePudding user response:

To apply a filter, you are essentially iterating over each item in the array and seeing if it matches your criteria. Return true if you want it to stay, and return false if you want it to be filtered out.

So at the top-most layer, you have an array of objects, each of which appears to represent a node (judging by the "nodeType" property). We start with this:

const matches = array.filter(node => {
  // criteria go here
  return true; // or false
});

What are the criteria? Well it should remain if...

  1. The node.user.name is "Adam"
  2. Of the writers, at least one has writer.name === "Adam"

Let's define those.

const hasUserNameAdam = (node) => node?.user?.name === "Adam";
const hasWriterNameAdam = (writer) => writer?.name === "Adam";

We can do the same thing with the writer array to handle the second layer.

const arrayHasWriterNameAdam = writerArray.some(writer => hasWriterNameAdam(writer));

Now we just need to plug them in.

const matches = data.filter(node => {
  const hasUserNameAdam = (node) => node?.user?.name === "Adam";
  const hasWriterNameAdam = (writer) => writer?.name === "Adam";
  const arrayHasWriterNameAdam = (writerArray) => writerArray.some(writer => hasWriterNameAdam(writer));

  return hasUserNameAdam(node) || arrayHasWriterNameAdam(node?.writers);
});

And we can choose to refactor those inner functions back to being in line to clean things up, if we would like.

const matches = data.filter(node => node?.user?.name === "Adam" || node?.writers?.some(writer => writer?.name === "Adam"));
  • Related