skip to Main Content

Could you please assist me on working out how can I filter for a specific property within a deep nested array of objects?

I want to be able to search for entire array (including parent itself and children) where _speciality is ‘can fly’. As such, in the above, I should get 2 values back (fruit1, fruit3).

I have tried to usual JS operations like .filter, .map but unable to work out how this can be achieved.

Here is what my object looks like:

const foo = {
    "fruits": [
        {
              "fruit1": [{
              "categories": { "shape": "square", "size": "large"},
              "factories": [{ "city": "delhi", "location": "23 new road"}],
              "capacity": [{ "weight": "10kg", "_speciality": "can fly"}]    
              }]
        },
        {
            "fruit2": [{
              "categories": { "shape": "round", "size": "small"},
              "factories": [{ "city": "bombay", "location": "13 new road"}],
              "capacity": [{ "weight": "14kg", "_speciality": "can sing"}]      
              }]        
        },
        {
            "fruit3": [{
              "categories": { "shape": "rectangle", "size": "medium"},
              "factories": [{ "city": "bombay", "location": "13 new road"}],
              "capacity": [{ "weight": "14kg", "_speciality": "can fly"}]      
              }]        
        }        
    ]
}

2

Answers


  1. You will need to tailor your filter to your data. There is no one-size-fits-all approach to this.

    Your filter is going to look something like this:

    const canFly = data.fruits.filter(obj =>
      obj[Object.keys(obj)[0]][0].capacity[0]._speciality === 'can fly');
    

    In the snippet below, I introduced some intermediary variables to explain the process in more detail.

    const data = {
      "fruits": [{
        "fruit1": [{
          "categories": { "shape": "square", "size": "large"},
          "factories": [{ "city": "delhi", "location": "23 new road"}],
          "capacity": [{ "weight": "10kg", "_speciality": "can fly"}]    
        }]
      }, {
        "fruit2": [{
          "categories": { "shape": "round", "size": "small"},
          "factories": [{ "city": "bombay", "location": "13 new road"}],
          "capacity": [{ "weight": "14kg", "_speciality": "can sing"}]      
        }]        
      }, {
        "fruit3": [{
          "categories": { "shape": "rectangle", "size": "medium"},
          "factories": [{ "city": "bombay", "location": "13 new road"}],
          "capacity": [{ "weight": "14kg", "_speciality": "can fly"}]      
        }]        
      }]
    };
    
    const canFly = data.fruits.filter(obj => {
      const
        fruitKeyArr = Object.keys(obj), // We do not know the key
        fruitKey = fruitKeyArr[0], // Let's grab the first one
        fruitArr = obj[fruitKey], // The value is an array
        fruitData = fruitArr[0], // Grab the first one; again
        fruitCapacityArr = fruitData.capacity; // Access the capacity
      return fruitCapacityArr[0]._speciality === 'can fly'; // Compare
    });
    
    const keys = canFly.map(obj => Object.keys(obj)[0]);
    
    console.log(JSON.stringify(keys)); // ["fruit1","fruit3"]
    console.log(canFly);
    .as-console-wrapper { top: 0; max-height: 100% !important; }

    The results should be:

    ["fruit1", "fruit3"]
    
    [{
      "fruit1": [{
        "categories": { "shape": "square", "size": "large"},
        "factories": [{ "city": "delhi", "location": "23 new road"}],
        "capacity": [{ "weight": "10kg", "_speciality": "can fly"}]    
      }]
    }, {
      "fruit3": [{
        "categories": { "shape": "rectangle", "size": "medium"},
        "factories": [{ "city": "bombay", "location": "13 new road"}],
        "capacity": [{ "weight": "14kg", "_speciality": "can fly"}]      
      }]        
    }]
    
    Login or Signup to reply.
  2. Here is one of the many solutions you are looking for

    const foo = {
        "fruits": [
            {
                  "fruit1": [{
                  "categories": { "shape": "square", "size": "large"},
                  "factories": [{ "city": "delhi", "location": "23 new road"}],
                  "capacity": [{ "weight": "10kg", "_speciality": "can fly"}]    
                  }]
            },
            {
                "fruit2": [{
                  "categories": { "shape": "round", "size": "small"},
                  "factories": [{ "city": "bombay", "location": "13 new road"}],
                  "capacity": [{ "weight": "14kg", "_speciality": "can sing"}]      
                  }]        
            },
            {
                "fruit3": [{
                  "categories": { "shape": "rectangle", "size": "medium"},
                  "factories": [{ "city": "bombay", "location": "13 new road"}],
                  "capacity": [{ "weight": "14kg", "_speciality": "can fly"}]      
                  }]        
            }        
        ]
    };
    
    const result = foo['fruits'].filter(f => {
      const keyName = Object.keys(f)[0];
      const _speciality = f[keyName][0]['capacity'][0]['_speciality'];
      return _speciality === 'can fly';
    });
    
    console.log(result)

    You can easily process the result to get the output as required. I am leaving that exercise for you but feel free to get back.

    Happy Coding!!

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search