最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

In Node.jsJavascript, how to check if value exists in multidimensional array? - Stack Overflow

programmeradmin0浏览0评论

Lets say I have array something like this:

$game = Array
(
    ['round'] => Array
        (
            ['match'] => Array
                (
                    ['player_2'] => Array
                        (
                            [name] => asddd
                            [id] => 1846845
                            [winner] => yes
                        )

                    ['player_21'] => Array
                        (
                            [name] => ddd
                            [id] => 1848280
                            [winner] => no
                        )

                )
        )
)

And lets say in Node.js/Javascript I need to check if player_3 winner key value is yes. In PHP, you did something like this:

if( $game['round']['match'][player_3]['winner'] == 'yes'){

}

Because there is no player_3 it returns false in PHP, but if I did something similar in Javascript:

 if( typeof game['round']['match'][player_3]['winner'] != 'undefined' && game['round']['match'][player_3]['winner'] == 'yes'){

 }

I would get error: (node:15048) UnhandledPromiseRejectionWarning: TypeError: Cannot read property '0' of undefined, because player_3 doesn't exist in array and you can't check key value of array, that doesn't exist.

You could do this in Javascript:

if( 
   typeof game['round'] != 'undefined' &&
   typeof game['round']['match'] != 'undefined' &&
   typeof game['round']['match']['player_3'] != 'undefined' &&
   typeof game['round']['match']['player_3']['winner'] != 'undefined' &&
   typeof game['round']['match']['player_3']['winner'] == 'yes'
){
   var playerIsWinner = true;
}else{
   var playerIsWinner = false;
}

You check each array inside array from top down and make sure that they exists. I don't know if it actually works, but even if it does, it seems bad and stupid way to check something. I mean look how simple it is in PHP, while in Javascript I have to check each array existence inside array. So is there better way checking value of array?

Lets say I have array something like this:

$game = Array
(
    ['round'] => Array
        (
            ['match'] => Array
                (
                    ['player_2'] => Array
                        (
                            [name] => asddd
                            [id] => 1846845
                            [winner] => yes
                        )

                    ['player_21'] => Array
                        (
                            [name] => ddd
                            [id] => 1848280
                            [winner] => no
                        )

                )
        )
)

And lets say in Node.js/Javascript I need to check if player_3 winner key value is yes. In PHP, you did something like this:

if( $game['round']['match'][player_3]['winner'] == 'yes'){

}

Because there is no player_3 it returns false in PHP, but if I did something similar in Javascript:

 if( typeof game['round']['match'][player_3]['winner'] != 'undefined' && game['round']['match'][player_3]['winner'] == 'yes'){

 }

I would get error: (node:15048) UnhandledPromiseRejectionWarning: TypeError: Cannot read property '0' of undefined, because player_3 doesn't exist in array and you can't check key value of array, that doesn't exist.

You could do this in Javascript:

if( 
   typeof game['round'] != 'undefined' &&
   typeof game['round']['match'] != 'undefined' &&
   typeof game['round']['match']['player_3'] != 'undefined' &&
   typeof game['round']['match']['player_3']['winner'] != 'undefined' &&
   typeof game['round']['match']['player_3']['winner'] == 'yes'
){
   var playerIsWinner = true;
}else{
   var playerIsWinner = false;
}

You check each array inside array from top down and make sure that they exists. I don't know if it actually works, but even if it does, it seems bad and stupid way to check something. I mean look how simple it is in PHP, while in Javascript I have to check each array existence inside array. So is there better way checking value of array?

Share Improve this question asked Aug 28, 2018 at 15:49 user1203497user1203497 5173 gold badges11 silver badges18 bronze badges 2
  • You could wrap it in a try...catch block – Luca Kiebel Commented Aug 28, 2018 at 15:51
  • 1 Possible duplicate of How to check if array has nested property with defined value – fsinisi90 Commented Aug 28, 2018 at 15:52
Add a ment  | 

5 Answers 5

Reset to default 2

Please, look at the lodash library, especially at methods, such as get. Then you may safely try something like:

_.get(game, 'round.match.player3.winner', false);

That's it :)

The array you've shown resembles more of an object in JS. So here's what you could possibly try.

const obj = {
  round: {
    match: {
      player_2: {
        name: 'asddd',
        id: 1846845,
        winner: true
      },
      player_21: {
        name: 'ddd',
        id: 1848280,
        winner: false
      }
    }
  }
}

...

const isWinner = (key) => {
  try {
    return obj.round.match[key].winner
  } catch(e) {
    return false
  }
}


console.log(isWinner('player_2'))

By wrapping your return inside of try ... catch, you prevent the error from being thrown at your query and possibly stopping the app from continuing on. If from whatever reason the structure of your object would change, you'd still have a boolean value returned.

If you have to keep your winner value in form of a string, you could simply pare the value, and you'll end up with boolean as a result. As so:

const isWinner = (key) => {
  try {
    return (obj.round.matchs[key].winner === 'yes')
  } catch(e) {
    return false
  }
}

No you don't need to do manual check for deeply nested data for null or undefined, instead you could rollout your own small but pact function in this case get and be flexible with any input data provided. See more about Array.prototype.reduce()

// this single line will do the trick
const get = (p, o) =>p.reduce((xs, x) => (xs && xs[x]) ? xs[x] : null, o)

// let's pass in our props object...

const props = {"round":{"match":[{"player_21":{"name":"asdfg","id":1846845,"winner":"not yet"}},{"player_2":{"name":"sany","id":1846280,"winner":"no"}},{"player_3":{"name":"sunny","id":1846000,"winner":"yes"}}]}}

var playerIsWinner = false;
//console.log(get(['round', 'match', 2, 'player_3', 'winner'], props))
if (get(['round', 'match', 2, 'player_3', 'winner'], props) == 'yes') {
  playerIsWinner = true;
}

console.log(playerIsWinner)

You can do the following to avoid the undefined error:

 if ( game['round']['match'][player_3] && game['round']['match'][player_3]['winner'] == 'yes' ) {
   ...
 }

Because undefined is "falsey" you'll get false instead of undefined if player_3 does not exist, and true if player_3 exists and is the winner.

Just wrap in a try catch block. This allows you to skip all of your boilerplate typeof statements:

   typeof game['round'] != 'undefined' &&
   typeof game['round']['match'] != 'undefined' &&
   typeof game['round']['match']['player_3'] != 'undefined' &&
   typeof game['round']['match']['player_3']['winner'] != 'undefined' &&
   typeof game['round']['match']['player_3']['winner'] == 'yes'

Instead throw an error and handle it if a element is not present. For example:

let nestedObj = {
  prop1: {
    propa1: {
      propb1: 'test'
    }
  },
  prop2: {}
}

try {
  console.log(nestedObj['prop1']['propa1']['propb1']);
  console.log(nestedObj['prop2']['propa2']['propb2']);
} catch(e) {
  console.log('prop not defined');
}

This is a lot simpler than checking for every simple condition like you are doing now.

发布评论

评论列表(0)

  1. 暂无评论