Source: app/util/bitwiseUtils/index.js

/**
 * Check that the bitwise value contains the passed in flag
 *
 * @param value the whole bitwise value, typically returned from the api
 * @param flag - the value (flag) which you'd like to check
 * @returns {integer} - 0 or 1 (0 = false, 1 = true)
 * @example bitwiseFlagCheck(item.category, STRENGTHENING)
 */

/* eslint-disable no-bitwise  */
export const hasFlag = (value, flag) => (value & flag) === flag;

/**
 * return availble flags from a list of flags, availbe in a data set
 *
 * @param sourceData | array of flags e.g. [1, 42, 40, 32]
 * @param flags | Object of complete set of flags eg {0: 'bill', 1: 'dave', 2: 'shela', 3: 'john', 4: 'shazza', 5: 'tracy'}
 * @returns set of availbe flags | {0: 'bill', 1: 'dave',3: 'john', 5: 'tracy'}
 * @example availableFlags([1,4], flags)
 */
export const availableFlags = (sourceData, flags) =>
  sourceData &&
  sourceData.length > 0 &&
  sourceData.reduce((acc, cur) => {
    Object.keys(flags).forEach(flagIndex => {
      if (hasFlag(cur, 1 << parseInt(flagIndex, 10))) {
        acc[flagIndex] = flags[flagIndex]; // eslint-disable-line
      }
    });
    return acc;
  }, {});

/**
 * return a single bitwise value based of an array of flags
 * @param {string} flags | array of flags e.g. [1, 5, 18, 4]]
 * @returns {number} | bitwise value
 * @example convertArrayToBitwise([1, 5, 18, 4])
 * */
export const convertArrayToBitwise = flags => flags.reduce((a, b) => a | (1 << b), 0);

/**
 * return a array of values that match within a bitwise
 * @param {number} | bitwise value
 * @returns {array} | An array of numbers | []
 * @example convertBitwiseToArray(2284)
 * */
export const convertBitwiseToArray = bitwise =>
  parseInt(bitwise, 10)
    .toString(2)
    .split('')
    .reverse()
    .map((val, index) => (val === '1' ? index : null))
    .filter(val => val !== null);