2

I am trying to install some logic into a piece of JS I am working on that will simply add/remove flags depending on some conditions.

It primarily consists of two steps

  1. Build object based on some stateful data
  2. Hand off to post initialization method to parse data array of objects

In Step 1, there is a 'status' property, which can have a number of flags:

  - INCOMPLETE      = 1
  - COMPLETE        = 2
  - CURRENT         = 4
  - NOT_APPLICABLE  = 8

When the object array is parsed, it checks each item to see what status flags are set:

  if CURRENT is set, give class 'item-current' to node
  if INCOMPLETE is set, give class 'item-incomplete' to node
  if COMPLETE is set, give class 'item-complete' to node
  if NOT_APPLICABLE is set, give class 'item-not-applicable' to node

As the user interacts with the page, the flags will change on the object array - when a user 'completes' a segment, the status for that object property will remove the INCOMPLETE flag, and add the COMPLETE flag.

I tried doing this this way:

   let v = [
       {
         name: "Item 1",
         status: COMPLETE
       },
       {
         name: "Item 2",
         status: INCOMPLETE | CURRENT
       },
       {
         name: "Item 3",
         status: INCOMPLETE
       }
   ];

   // Moving on to step 3

   v[1].status = v[1].status ^ INCOMPLETE ^ CURRENT | COMPLETE; // remove incomplete and current from Item 2, marking as COMPLETE
   v[2].status = v[2].status | CURRENT;  // marks Item 3 as current step, but not yet complete

In the above scenario, Item 1 has been completed, and the user has moved on to Item 2 which is still INCOMPLETE, and CURRENT step. For some reason, when I am evaluating the conditions of the flags, it gives me (what seems like) unexpected behavior.

I have tried removing the flag by doing these: v[1].status ^= CURRENT v[1].status = v[1].status ^ CURRENT

And comparing by:

if ((v[1].status & COMPLETE) === COMPLETE) {
  // is complete
} else {
  // not complete
}

But yet I still seem to face flags seeming like they are still set, or unexpectedly getting set. Is there an easier way to do this?

The desired result, would be a case where I can set the flag, remove the flag, and check to see if the flag is set - using constants that are bitmasks.

Why is INCOMPLETE | CURRENT the same thing as INCOMPLETE ^ CURRENT?

I am struggling with removing a bit from the mask and returning that value it seems.

3
  • please add the wanted result. Commented Feb 2, 2022 at 15:52
  • Bitwise operators operate on integers. If you want to have separate independent flags, you need to number them as powers of 2: 1, 2, 4, 8, 16, etc. Commented Feb 2, 2022 at 16:09
  • Sorry, that was a typo, They are 1,2,4,8 Commented Feb 2, 2022 at 17:01

1 Answer 1

3

You can't use bitwise operations like this with values that are not powers of 2.

The value 3 could be any of the follwing values:

  • CURRENT
  • COMPLETE | INCOMPLETE
  • CURRENT | COMPLETE
  • CURRENT | INCOMPLETE
  • CURRENT | COMPLETE | INCOMPLETE

There's no way to tell which combination it is.

Change the values to

  • COMPLETE = 1
  • COMPLETE = 2
  • CURRENT = 4
  • NOT_APPLICABLE = 8

and it's so easy to do bitwise operations with powers of 2.

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

4 Comments

Why is COMPLETE | CURRENT the same thing as COMPLETE ^ CURRENT
My values are actually powers of 2, not 1,2,3,4 - it was a typo on my part. Sorry!
Can you unconditionally remove a bitmask flag? Like say, you have A = 1, and then do A ^ 4 - it returns 5; ideally I'd like it to return 1.
5 & (0xff ^ 4) - 0xff ^ 4 will set bit pattern to b11111011 which you then & with 5 (b00000101) to get 1 (b00000001). Just make sure that the value you use for 0xff is greater than the largest flag

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.