【问题标题】:How to check if object has an array [duplicate]如何检查对象是否有数组[重复]
【发布时间】:2019-02-05 00:52:59
【问题描述】:

我有以下对象:

[ 13,
  { a: [ 
         [ '2988.30000', '0.19000000', '1549294216.653040' ] 
    ] 
  },
  { b: [ 
         [ '2988.30000', '0.00000000', '1549294216.653774' ],
         [ '2985.30000', '0.20000000', '1549294216.558703' ],
         [ '2982.00000', '0.08000000', '1549294195.246025' ],
         [ '2956.00000', '0.07686000', '1549287593.202601' ],
         [ '2802.00000', '0.93779146', '1549187562.171529' ],
         [ '1702.50000', '0.05873000', '1548923730.844040' ] 
    ] 
  } 
]

如何检查数组'b'的元素是否存在?

编辑 'b' 数组可能位于不同的位置,在 'a' 之前,在 '13' 之前,甚至可能不存在。

【问题讨论】:

  • @Bodrov 在那个问题中,他所要做的就是降低一个级别,但在我的情况下,该级别可能不存在 obj[2].hasOwnProperty('b') 并抛出 TypeError: Cannot read property 'b' 未定义。
  • 有哪些不同的条件需要检查?输入可以是一个空数组吗? { b: [...] } 是否存在但在数组中的不同位置?是否存在具有多个数组属性的对象?如果有多个 { b: [...] } 条目怎么办?
  • @user633183 这是来自 websocket 的消息,我必须根据它做不同的事情:kraken.com/features/websocket-api#message-book
  • data.find(x => Object(x) === x && x.hasOwnProperty('b') && Array.isArray(x.b)) !== undefined // => true - 这就是说,我敢肯定你的做法是错误的。与其在运行时搜索数据并检查数据类型,不如选择一个定义明确的数据结构,以便您的程序可以了解依赖

标签: javascript arrays node.js object


【解决方案1】:

您可以将find() 与您要检查的条件一起使用。如果某个元素满足条件则返回,否则返回undefined

const arr = [
  13,
  {a: [
    ['2988.30000', '0.19000000', '1549294216.653040']
  ]},
  {b: [
    ['2988.30000', '0.00000000', '1549294216.653774'],
    ['2985.30000', '0.20000000', '1549294216.558703'],
    ['2982.00000', '0.08000000', '1549294195.246025'],
    ['2956.00000', '0.07686000', '1549287593.202601'],
    ['2802.00000', '0.93779146', '1549187562.171529'],
    ['1702.50000', '0.05873000', '1548923730.844040']
  ]}
];

let res = arr.find(
    x => x.hasOwnProperty("b") && Array.isArray(x.b)
);

console.log(res);

【讨论】:

    【解决方案2】:

    所以它来自 Kraken API,并且数据确实有保证的形状,其中asbs已知键 -

    [ Integer                           // channel
    , { as: [ [ Float, Float, Float ] ] // [ price, volume, timestamp ]
    , { bs: [ [ Float, Float, Float ] ] // [ price, volume, timestamp ]
    ]
    

    循环遍历您的对象并动态搜索属性的建议(包括我在上面的评论中的建议)是XY problem 的结果。在这种情况下,我会使用解构赋值 -

    const messageBook =
      [ 0
      , { as:
            [ [ 5541.30000, 2.50700000, 1534614248.123678 ]
            , [ 5541.80000, 0.33000000, 1534614098.345543 ]
            , [ 5542.70000, 0.64700000, 1534614244.654432 ]
            ]
        }
      , { bs:
            [ [ 5541.20000, 1.52900000, 1534614248.765567 ]
            , [ 5539.90000, 0.30000000, 1534614241.769870 ]
            , [ 5539.50000, 5.00000000, 1534613831.243486 ]
            ]
         }
      ]
      
                        // !          !       !  
    const doSomething = ([ channel, { as }, { bs } ]) =>
      console.log(channel, as, bs)
      // 0 [...] [...]
        
    doSomething(messageBook)

    如果你不能信任生产者,你可以将解构赋值与默认参数结合使用——

    const badMessageBook =
      [ 0
      , { as:
            [ [ 5541.30000, 2.50700000, 1534614248.123678 ]
            , [ 5541.80000, 0.33000000, 1534614098.345543 ]
            , [ 5542.70000, 0.64700000, 1534614244.654432 ]
            ]
        }
        // missing { bs: [ ... ] }
      ]
      
                        //         !           !                    !  
    const doSomething = ([ channel = 0, { as } = { as: [] }, { bs } = { bs: [] } ]) =>
      console.log(channel, as, bs)
      // 0 [...] [...]
        
    doSomething(badMessageBook)

    在这种情况下,您的函数会变得有点长。您可以使用多行来增加可读性 -

    const doSomething =         // helpful whitespace emerges...
      ( [ channel = 0           // default channel 0  
        , { as } = { as: [] }   // sometimes excluded by Kraken
        , { bs } = { bs: [] }   // sometimes excluded by Kraken
        ]
      ) => console.log(channel, as, bs)   // doSomething 
    

    【讨论】:

    • 谢谢。虽然asbs 是已知键,但ab 可能不存在,或者两者可以同时存在。我不喜欢依赖第 3 方的保证,所以我需要确保它存在,而不是仅仅假设这涉及大量资金。
    • 我进行了更新,向您展示如何使用默认参数处理格式错误的有效负载
    • 我相信这个解决方案对他来说会更好,你有我的支持+1。
    【解决方案3】:

    const arr = [13,
      {
        a: [
          ['2988.30000', '0.19000000', '1549294216.653040']
        ]
      },
      {
        b: [
          ['2988.30000', '0.00000000', '1549294216.653774'],
          ['2985.30000', '0.20000000', '1549294216.558703'],
          ['2982.00000', '0.08000000', '1549294195.246025'],
          ['2956.00000', '0.07686000', '1549287593.202601'],
          ['2802.00000', '0.93779146', '1549187562.171529'],
          ['1702.50000', '0.05873000', '1548923730.844040']
        ]
      }
    ];
    
    
    arr.forEach(el => {
      if (el.hasOwnProperty('b')) {
        console.log(Array.isArray(Object.values(el)));
      }
    });
    
    //solution 2 :
    
    
    let res2 = arr.findIndex(e => e && e['b'] && Array.isArray(e['b'])) > -1;
    
    console.log(res2);

    【讨论】:

    • 我收到此错误:arr.forEach is not a function
    • 用同样的例子你不会得到任何错误
    【解决方案4】:

        let list = [ 13,
          { a: [ [ '2988.30000', '0.19000000', '1549294216.653040' ] ] },
          { b:
             [ [ '2988.30000', '0.00000000', '1549294216.653774' ],
               [ '2985.30000', '0.20000000', '1549294216.558703' ],
               [ '2982.00000', '0.08000000', '1549294195.246025' ],
               [ '2956.00000', '0.07686000', '1549287593.202601' ],
               [ '2802.00000', '0.93779146', '1549187562.171529' ],
               [ '1702.50000', '0.05873000', '1548923730.844040' ] ] } ];
    
        if (arrayContainsObject('b', list)) {
          console.log('list key b is an Array');
        }
    
        function arrayContainsObject(obj, list) {
          for (var i = 0; i < list.length; i++) {
            if ((typeof list[i] === 'object') && (list[i].hasOwnProperty(obj))) {
              return true;
            }
          }
          return false;
        }

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-18
      • 2015-08-24
      • 2018-12-23
      • 1970-01-01
      相关资源
      最近更新 更多