Efficient Flag Management with Bitwise Operations and Reduce

April 28, 2025

Bitwise Flags

  1. What bitwise flags are
  2. Defining and combining flags in TypeScript and plain JavaScript
  3. Storing and retrieving the bitmask
  4. Decoding with a simple loop
  5. Rewriting that loop using

    Array.prototype.reduce

  6. Pros, cons, and when to use each style

1. Understanding Bitwise Flags

A bitwise flag uses each bit in an integer to represent an on/off value:

  • Set a flag:

    mask |= FLAG

  • Test a flag:

    (mask & FLAG) !== 0

  • Clear a flag:

    mask &= ~FLAG

  • Toggle a flag:

    mask ^= FLAG

Using shifts (

1 << n

) assigns each flag a power-of-two value.


2. Defining Flags

TypeScript

enum ActivityEnum { Kitesurfing = 1 << 0, // 1 (00000001) Hiking = 1 << 1, // 2 (00000010) Cycling = 1 << 2, // 4 (00000100) Fishing = 1 << 3, // 8 (00001000) HuntingDuck = 1 << 4, // 16 (00010000) HuntingDeer = 1 << 5, // 32 (00100000) Running = 1 << 6, // 64 (01000000) Surfing = 1 << 7, // 128 (10000000) }

Plain JavaScript

const ActivityFlags = Object.freeze({ Kitesurfing: 1 << 0, // 1 Hiking: 1 << 1, // 2 Cycling: 1 << 2, // 4 Fishing: 1 << 3, // 8 HuntingDuck: 1 << 4, // 16 HuntingDeer: 1 << 5, // 32 Running: 1 << 6, // 64 Surfing: 1 << 7, // 128 })

let mask = ActivityEnum.Kitesurfing | ActivityEnum.Fishing // mask === 1 | 8 === 9

  1. Storing & Retrieving

// 1) Read raw string const storedString = localStorage.getItem('activities'); // e.g. "9" or null // 2) Fallback to "0" const stringOrZero = storedString !== null ? storedString : '0'; // 3) Parse to integer const mask = parseInt(stringOrZero, 10); // mask === 9

  1. Decoding with a Simple Loop

function decodeActivities(mask) { const active = []; for (const [name, bit] of Object.entries(ActivityFlags)) { if ((mask & bit) !== 0) { active.push(name); } } return active; } console.log(decodeActivities(9)); // → ["Kitesurfing", "Fishing"]

  1. Decoding with reduce

const active = Object .entries(ActivityFlags) .reduce((acc, [name, bit]) => { if ((mask & bit) !== 0) { acc.push(name); } return acc; }, []); console.log(active); // → ["Kitesurfing", "Fishing"]

Or immutably:

const activeImmutable = Object .entries(ActivityFlags) .reduce((acc, [name, bit]) => (mask & bit) !== 0 ? [...acc, name] : acc , []);

Disclaimer: The views and opinions expressed in this blog post are solely my own and do not reflect the views of my employer, colleagues, or any affiliated organization.