-1

I have the following object:

[ 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' ] 
    ] 
  } 
]

How can I check if the element with the array 'b' exists?

EDIT The 'b' array might be in a different position, before 'a', before '13', and might not even exist.

6
  • google.com/search?q=javascript+is+array Commented Feb 4, 2019 at 16:13
  • @Bodrov In that question all he has to do is drop down one level but in my case that level might not exist obj[2].hasOwnProperty('b') and throw TypeError: Cannot read property 'b' of undefined. Commented Feb 4, 2019 at 16:14
  • What are the different conditions that need to be checked? Could the input be an empty array? Could { b: [...] } exist but be in a different position in the array? Could there be an object with multiple array properties? What if there are multiple entries with { b: [...] }? Commented Feb 4, 2019 at 16:15
  • @user633183 This is a message from a websocket and I have to do different stuff depending on it: kraken.com/features/websocket-api#message-book Commented Feb 4, 2019 at 16:21
  • data.find(x => Object(x) === x && x.hasOwnProperty('b') && Array.isArray(x.b)) !== undefined // => true - that said, I'm sure you're going about this the wrong way. Instead of searching through your data and inspecting data types at runtime, you should choose a well-defined data structure such that you program can know about and rely upon. Commented Feb 4, 2019 at 16:22

4 Answers 4

2

You can use find() with the conditions you want to check. if some element accomplish the conditions it is returned, otherwise undefined is returned.

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

Sign up to request clarification or add additional context in comments.

Comments

2

So it's coming from Kraken API and the data does have a guaranteed shape, where as and bs are known keys -

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

Suggestions (including my own in the comment above) to loop through your object and dynamically search for the property are the result of XY problem. In this case I would use destructuring assignment -

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)

In the event you cannot trust the producer, you can use destructuring assignment in combination with default arguments –

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)

In this case, your function gets a little long. You can use multiple lines for added readability -

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 

3 Comments

Thank you. While as and bs are known keys, either a and b might not exist or both can exist at the same time. I don't like to rely on guarantees from 3rd parties so I need to make sure it is there and not just assume as this is dealing with a lot of money.
I made an update to show you how to work with a badly-formed payload using default arguments
I believe this solution will be better for him, you have my support +1.
0

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

2 Comments

I get this error: arr.forEach is not a function
with the same example you re not gonna get any errors
0

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.