Reputation: 1145
Say I have the following code:
class Restaurant
{
const FRUITS = 1;
const VEGETABLES = 2;
const MEET = 4;
static public $data = [
self::FRUITS => ['apple', 'banana'],
self::VEGETABLES => ['tomato', 'potato'],
self::MEET => ['beef', 'pig']
];
public static function getSomething($byte)
{
// unknown logic for me
}
}
Restaurant::getSomething(Restaurant::FRUITS | Restaurant::MEET);
// ['apple', 'banana', 'beef', 'pig']
I need to implement some logic which makes join operations based on bitwise operations.
What is the best way to do that?
Upvotes: 1
Views: 107
Reputation: 39542
Use ($byte & $bw) === $bw
where $byte
is whatever value you're testing with (eg. 3
) and $bw
is your bitwise value (eg. 1
, 2
or 4
) to check if bitwise values match.
Why does it work?
It's fairly simple. When we AND items, we're only using the bit values that are present in both values
$byte = 3 = 0011
$bw = 2 = 0010
AND'ed = 2 = 0010 (the same as $bw - $bw is included!)
^ 1 & 1 = 1
-----------------
$byte = 5 = 0101
$bw = 2 = 0010
AND'ed = 0 = 0000 (empty as the values do not match - $bw is NOT included)
^ 0 & 1 = 0
Code:
<?php
class Restaurant
{
const FRUITS = 1; // 0001
const VEGETABLES = 2; // 0010
const MEET = 4; // 0100
static public $data = [
self::FRUITS => ['apple', 'banana'],
self::VEGETABLES => ['tomato', 'potato'],
self::MEET => ['beef', 'pig']
];
public static function getSomething($byte)
{
// Start with an empty array
$returnItems = array();
// Loop through our bitwise values
foreach (self::$data as $bw => $items) {
// Is it included in $byte?
if (($byte & $bw) === $bw) {
// Then add the items in $items to $returnItems
$returnItems = array_merge($returnItems, $items);
}
}
// Return the items
return $returnItems;
}
}
Test:
$result = Restaurant::getSomething(Restaurant::FRUITS | Restaurant::MEET); // 5 - 0101
var_dump($result);
/*
array(4) {
[0]=>
string(5) "apple"
[1]=>
string(6) "banana"
[2]=>
string(4) "beef"
[3]=>
string(3) "pig"
}
*/
Upvotes: 4
Reputation: 375
Nothing too fancy I'd say...
public static function getSomething($bitmask)
{
$result = [];
foreach(self::$data as $key => $value)
{
if(($key & $bitmask) !== 0)
{
$result = array_merge($result, $value);
}
}
return $result;
}
Upvotes: 1