skip to Main Content

Struggling to get my head around this one, and I find it quite tricky to explain so will do my best.

What I am trying to do is use a number to show allergens in foods. So for example an entry in the database could be "falafel" which has an allergen code of 16448 that is currently stored in the database.

What I need to do is take this number and convert it to hex, which gives me 4040.

I have this array of allergens


    $allergens = array(
      "celery"      => array("label" => "Celery",      "short" => "", "value" => 0x00000001),
      "crustaceans" => array("label" => "Crustaceans", "short" => "", "value" => 0x00000002),
      "eggs"        => array("label" => "Eggs",        "short" => "", "value" => 0x00000010),
      "fish"        => array("label" => "Fish",        "short" => "", "value" => 0x00000020),
      "gluten"      => array("label" => "Gluten",      "short" => "", "value" => 0x00000040),
      "lupin"       => array("label" => "Lupin",       "short" => "", "value" => 0x00000080),
      "milk"        => array("label" => "Milk",        "short" => "", "value" => 0x00000100),
      "molluscs"    => array("label" => "Molluscs",    "short" => "", "value" => 0x00000200),
      "mustard"     => array("label" => "Mustard",     "short" => "", "value" => 0x00000400),
      "nuts"        => array("label" => "Nuts",        "short" => "", "value" => 0x00001000),
      "peanuts"     => array("label" => "Peanuts",     "short" => "", "value" => 0x00002000),
      "sesame"      => array("label" => "Sesame",      "short" => "", "value" => 0x00004000),
      "soya"        => array("label" => "Soya",        "short" => "", "value" => 0x00008000),
      "sulphur"     => array("label" => "Sulphur",     "short" => "", "value" => 0x00010000),
    );

I then need to go through here, and see where 4040 matches. So in this case it would be gluten (40), and sesame (4000).

Another example would be a dish that has an allergens code of 320. Converted to hex this is 800. So I would need to return the labels for values of 400, 200, 100, 80, and 20 from the above array.

The numbers in the DB I cannot change. The array I posted above was in code that was previously used in the website that is no longer working.

Another example is something in the DB has 96 as it’s allergens code. Which in hex is 60, which can be made of 40 and 20 from the array which makes sense given this food. I know the values in the table are not in hex. But I need to convert them to hex, and then with this hex number find how it can be made from the numbers in the array and return the labels based on these numbers

How can I achieve this? Hopefully my explanation makes sense.

2

Answers


  1. Chosen as BEST ANSWER

    Found a way to make it work. I pass in the number from the DB and array of allergens to this function -

    static function findMatchingLabels($number, $allergens)
      {
        $hexNumber = dechex($number);
        $matchingLabels = array();
    
        foreach ($allergens as $allergen) {
          if ($allergen['value'] & hexdec($hexNumber)) {
            $matchingLabels[] = $allergen['label'];
          }
        }
    
        return $matchingLabels;
      }
    

  2. (@sunnyj58 In continuation from our discussion in comments)

    The values in the table represent a bitmask as first alluded to by @shingo in comments.

    The "bitmask system" revealed from your table uses 14 of the bits in a 16-bit integer (unsigned).

    The allergen themselves are like checkboxes (bits).

    Hex(Base16)  Base10        Allergen
    -----------  ------        --------
    0x00000001        1        Celery
    0x00000002        2        Crustaceans
    0x00000010       16        Eggs
    0x00000020       32        Fish
    0x00000040       64        Gluten
    0x00000080      128        Lupin
    0x00000100      256        Milk
    0x00000200      512        Molluscs
    0x00000400     1024        Mustard
    0x00001000     4096        Nuts
    0x00002000     8192        Peanuts
    0x00004000    16384        Sesame
    0x00008000    32768        Soya
    0x00010000    65536        Sulphur
    

    Using this table as a guide I will present a solution which will intrinsically infer an algorithm. However I wont be using hexadecimal to present the solution, though you can later if you find it easier to work with.

    Input: 
    
    "falafel" which has an allergen code of 16448
    
    Algorithm:
    
    is 16448 >= 65546? no
    is 16488 >= 32768? no
    is 16488 >= 16384? yes --> Sesame
      Find the difference: subtract 16384 from 16488 = 104
    is 104 >= 8192? no
    is 104 >= 4096? no
    is 104 >= 1024? no
    if 104 >= 512? no
    is 104 >= 256? no
    is 104 >= 128? no
    is 104 >= 64? yes --> Gluten
      Find the difference: subtract 64 from 104 = 40
    is 40 >= 32? yes --> Fish
      Find the difference: subtract 32 from 40 = 8
    is 8 >= 16? no
    is 8 >= 2? yes --> Crustaceans
      Find the difference: subtract 2 from 8 = 6
    is 6 >= 1? yes --> Celery
    
    Output:
    
    Sesame, Gluten, Fish, Crustaceans, Celery
    

    See if you can transform this into code. I’ll have to come back to this answer to update it with code later. (out of time).

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search