【问题标题】:In Node.js/Javascript, how to check if value exists in multidimensional array?在 Node.js/Javascript 中,如何检查值是否存在于多维数组中?
【发布时间】:2018-08-28 15:49:08
【问题描述】:

假设我有这样的数组:

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

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

                )
        )
)

假设在 Node.js/Javascript 中我需要检查 player_3 winner 键值是否为 yes。在 PHP 中,你做了这样的事情:

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

}

因为没有 player_3 它在 PHP 中返回 false,但如果我在 Javascript 中做了类似的事情:

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

 }

我会得到错误:(node:15048) UnhandledPromiseRejectionWarning: TypeError: Cannot read property '0' of undefined,因为数组中不存在player_3,并且您无法检查数组的键值,它不存在。

您可以在 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;
}

您从上到下检查数组中的每个数组并确保它们存在。我不知道它是否真的有效,但即使有效,检查某些东西似乎也是一种糟糕而愚蠢的方式。我的意思是看看它在 PHP 中是多么简单,而在 Javascript 中我必须检查每个数组是否存在于数组中。那么有没有更好的方法检查数组的值?

【问题讨论】:

标签: javascript arrays node.js


【解决方案1】:

请查看lodash 库,尤其是get 等方法。然后您可以安全地尝试以下方法:

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

就是这样:)

【讨论】:

    【解决方案2】:

    您展示的数组更像是 JS 中的对象。因此,您可以尝试以下方法。

    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'))
    

    通过将您的 return 包裹在 try ... catch 中,您可以防止在您的查询中引发错误并可能阻止应用程序继续运行。如果您的对象的结构由于某种原因发生变化,您仍然会返回一个布尔值。

    如果您必须将winner 值保留为字符串形式,您可以简单地比较该值,结果会得到布尔值。因此:

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

    【讨论】:

    • 我认为在这种情况下使用类似 lodash 的东西会更简单、更安全。它也将更具可读性。你不介意吗?
    • 肯定会更短,甚至更容易申请。但我不同意它更具可读性,特别是如果您不熟悉lodash。老实说,我不会安装 lodash 只是为了使用一次就忘记它
    【解决方案3】:

    不,您不需要手动检查 nullundefined 的深层嵌套数据,而是可以在这种情况下推出自己的小而紧凑的函数 get 并灵活处理提供的任何输入数据.查看更多关于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)

    【讨论】:

      【解决方案4】:

      您可以执行以下操作来避免未定义的错误:

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

      因为 undefined 是“falsey”,如果 player_3 不存在,你将得到 false 而不是 undefined,如果 player_3 存在并且是赢家,你会得到 true。

      【讨论】:

        【解决方案5】:

        只需包裹在 try catch 块中。这允许您跳过所有样板文件 typeof 语句:

           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'
        

        如果元素不存在,则抛出错误并处理它。例如:

        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');
        }

        这比像现在这样检查每个简单条件要简单得多。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-05-28
          • 1970-01-01
          • 2011-07-05
          • 2021-01-28
          • 2021-05-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多