Home > Enterprise >  How to exclude from foreach an array that does not contain an object?
How to exclude from foreach an array that does not contain an object?

Time:01-25

I'm receiving an array and performing a treatment to extract some information.

When I get the matrix like this, everything goes well!

[
  {
    averages: [
      [Object], [Object],
      [Object], [Object],
      [Object], [Object],
      [Object]
    ]
  },
  {
    averages: [
      [Object], [Object],
      [Object], [Object],
      [Object], [Object],
      [Object]
    ]
  },
  {
    averages: [
      [Object], [Object],
      [Object], [Object],
      [Object], [Object],
      [Object], [Object]
    ]
  },
  {
    averages: [
      [Object], [Object],
      [Object], [Object],
      [Object], [Object],
      [Object], [Object]
    ]
  }
]

But when the array comes like this:

[
  {
    averages: [
      [Object], [Object],
      [Object], [Object],
      [Object], [Object],
      [Object]
    ]
  },
  {
    averages: [
      [Object], [Object],
      [Object], [Object],
      [Object], [Object],
      [Object]
    ]
  },
  {
    averages: [
      [Object], [Object],
      [Object], [Object],
      [Object], [Object],
      [Object]
    ]
  },
  { averages: 'No data in period.' }
]

I get this error:

ccs.medias.forEach is not a function

Could this be the error?

{ averages: 'No data in period.' }

The code mentioned to filter the information I want is this:

    function test(arr) {
        let results = [];
        arr.forEach(ccs => {
          ccs.medias.forEach(element => {
            if (element["TYPE"] === 'AAA') {
              results.push(element["STATUS"])
            }
          })
        })
        return results;
    }

As I mentioned above, this code works for the first array example, but not for the following one. I appreciate if anyone can help me analyze it!

CodePudding user response:

Yep, you guessed right, problem is here:

{ averages: 'No data in period.' }

Before using .forEach(), you need to make sure property value (ccs.averages) is array, so just add simple if-condition like:

if (Array.isArray(ccs.averages)) {
  // Do what you need with array and only
}

Full code:

const arr = [
  {
    averages: [
      [Object], [Object],
      [Object], [Object],
      [Object], [Object],
      [Object]
    ]
  },
  {
    averages: [
      [Object], [Object],
      [Object], [Object],
      [Object], [Object],
      [Object]
    ]
  },
  {
    averages: [
      [Object], [Object],
      [Object], [Object],
      [Object], [Object],
      [Object]
    ]
  },
  { averages: 'No data in period.' }
]

function test(arr) {
  let results = [];
  arr.forEach(ccs => {
    // Make sure .avarages is array
    if (Array.isArray(ccs.averages)) {
      ccs.averages.forEach(element => {
      if (element["TYPE"] === 'AAA') {
        results.push(element["STATUS"])
      }
    })
    }
  })
  return results;
}

console.log(test(arr));

Refs: Array.isArray().

CodePudding user response:

As this question is tagged as "mongo", to do it in a query and retrieve results directly without the fields which are not an array you can use one of these queries:

For a find query you can add:

"averages": { "$type": "array }

Like this:

db.collection.find({
  "averages": {
    "$type": "array"
  }
})

Example here

Also if you are using an aggregation stage you can add a $match stage like this:

db.collection.aggregate([
  {
    "$match": {
      "averages": {
        "$type": "array"
      }
    }
  }
])

Example here

Note that the queries use $type

In this way you can avoid the loop.

  •  Tags:  
  • Related