Is there a simple way to manipulate bitwise enum in PHP? - php

I'm creating a custom user profile for a game (osu!) and I'm trying to get which "mods" has been used in a "top play".
The API provides a decimal number containing each mods the player used in his play.
Ex: 72 for DoubleTime+Hidden mods, since DoubleTime is 64 and Hidden 8
$hidden = 8;
$doubletime = 64;
$hiddendoubletime = ($hidden|$doubletime);
I want to, from 72 for example, know that its 8 and 64.
or even from 88 that it's 8 and 16 and 64.
I was thinking about transform 88 for example in binary (01011000), then detect all "1" positions since each "1" gives a mod.
Here : 01011000 -
the first "1" at position 4 is the Hidden mod, the second "1" a position 5 is the Hardrock mod and finally, the "1" at position 7 is the DoubleTime mod.
Then enum is the following :
enum Mods
{
None = 0,
NoFail = 1,
Easy = 2,
TouchDevice = 4,
Hidden = 8,
HardRock = 16,
SuddenDeath = 32,
DoubleTime = 64,
Relax = 128,
HalfTime = 256,
Nightcore = 512, // Only set along with DoubleTime. i.e: NC only gives 576
Flashlight = 1024,
Autoplay = 2048,
SpunOut = 4096,
Relax2 = 8192, // Autopilot
Perfect = 16384, // Only set along with SuddenDeath. i.e: PF only gives 16416
Key4 = 32768,
Key5 = 65536,
Key6 = 131072,
Key7 = 262144,
Key8 = 524288,
FadeIn = 1048576,
Random = 2097152,
Cinema = 4194304,
Target = 8388608,
Key9 = 16777216,
KeyCoop = 33554432,
Key1 = 67108864,
Key3 = 134217728,
Key2 = 268435456,
ScoreV2 = 536870912,
LastMod = 1073741824,
}
As you can see, the list is pretty big, so I can't just try each mods combinations in if() condition.

I would do something like this....
<?php
$user_options = 88;
$no_options = array ( 'None' => 0 );
$game_options = array (
'NoFail' => 1,
'Easy' => 2,
'TouchDevice'=> 4,
'Hidden' => 8,
'HardRock' => 16,
'SuddenDeath' => 32,
'DoubleTime' => 64,
'Relax' => 128,
'HalfTime' => 256,
'Nightcore' => 512,
'Flashlight' => 1024,
'Autoplay' => 2048,
'SpunOut' => 4096,
'Relax2' => 8192,
'Perfect' => 16384,
'Key4' => 32768,
'Key5' => 65536,
'Key6' => 131072,
'Key7' => 262144,
'Key8' => 524288,
'FadeIn' => 1048576,
'Random' => 2097152,
'Cinema' => 4194304,
'Target' => 8388608,
'Key9' => 16777216,
'KeyCoop' => 33554432,
'Key1' => 67108864,
'Key3' => 134217728,
'Key2' => 268435456,
'ScoreV2' => 536870912,
'LastMod' => 1073741824
);
$filtered = array_filter ( $game_options, function ( $value ) use ( $user_options )
{
return ( $value & $user_options ) == $value ? $value : NULL;
});
if ( empty ( $filtered ) )
{
print_r ( $no_options );
}
else
{
print_r ( $filtered );
}
?>

I was thinking, it would be best to only cycle through the user(s) set options, that way you don't have to cycle through all the game_options when maybe only a few lower numbered bits are set...
<?php
$user_options = 344;
$game_options = array (
'NoFail' => 1,
'Easy' => 2,
'TouchDevice'=> 4,
'Hidden' => 8,
'HardRock' => 16,
'SuddenDeath' => 32,
'DoubleTime' => 64,
'Relax' => 128,
'HalfTime' => 256,
'Nightcore' => 512,
'Flashlight' => 1024,
'Autoplay' => 2048,
'SpunOut' => 4096,
'Relax2' => 8192,
'Perfect' => 16384,
'Key4' => 32768,
'Key5' => 65536,
'Key6' => 131072,
'Key7' => 262144,
'Key8' => 524288,
'FadeIn' => 1048576,
'Random' => 2097152,
'Cinema' => 4194304,
'Target' => 8388608,
'Key9' => 16777216,
'KeyCoop' => 33554432,
'Key1' => 67108864,
'Key3' => 134217728,
'Key2' => 268435456,
'ScoreV2' => 536870912,
'LastMod' => 1073741824
);
function get_options ( $game_options, $user_options )
{
/* if no options are set, return this */
$nil = array ( 'None' => 0 );
/* if option(s) are set, return the array of set option(s) */
$set = array ( );
/* only loop the $game_options up until the max set $user_options */
$stop = $user_options;
foreach ( $game_options AS $on => $ov )
{
if ( $ov > $stop )
{
break;
}
else if ( ( $ov & $user_options ) == $ov )
{
$set[$on] = $ov;
$stop -= $ov;
}
}
return empty ( $set ) ? $nil : $set;
}
print_r ( get_options ( $game_options, $user_options ) );
?>

Related

How can I achieve this in Array in PHP

am having problem achieving this result with array, I want to update another empty array with data in first array in such a way that the first two rows is ommitted and the first 3rows is added to the index 0 of the empty array, and the next 3 rows is also updated to the second index and so on. I have this Array in
`$arr = [
'tqty' => 9,
'tPrice' => 18700,
'food_name_1' => 'Black Coffee',
'food_quanty_1' => 1,
'food_price_1' => 1000,
'food_name_2' => 'Sub Combo',
'food_quanty_2' => 2,
'food_price_2' => 3000
];`
I want to use this array data and update another empty array this way, removing the first two rows
$arr2 = [
0 => [
'food_name_1' => 'Black Coffee',
'food_quanty_1' => 1,
'food_price_1' => 1000
],
1 => [
'food_name_2' => 'Sub Combo',
'food_quanty_2' => 2,
'food_price_2' => 3000
]
];
here is my code so far
$arr = [
'tqty' => 9,
'tPrice' => 18700,
'food_name_1' => 'Black Coffee',
'food_quanty_1' => 1,
'food_price_1' => 1000,
'food_name_2' => 'Sub Combo',
'food_quanty_2' => 2,
'food_price_2' => 3000
];
$newdat = [];
$count = 0;
$oldcount = 1;
foreach($arr as $key => $value){
if(preg_match_all('!\d+!', $key, $matches)){
if($oldcount == $matches[0][0]){
$newdat[$matches[0][0]] = [
$count => [
$key => $value
]
];
} else{
$count = 0;
$oldcount = $matches[0][0];
}
}
$count++;
}
I hope I get help soon. thanks
Assuming the array keys and order stay consistent you could use array_chunk
<?php
$inArray = [
'tqty' => 9,
'tPrice' => 18700,
'food_name_1' => 'Black Coffee',
'food_quanty_1' => 1,
'food_price_1' => 1000,
'food_name_2' => 'Sub Combo',
'food_quanty_2' => 2,
'food_price_2' => 3000,
];
$outArray = [];
// Remove first 2 values.
$inArray = array_slice( $inArray, 2 );
// 'Chunk' the rest of the values.
// true preserves keys.
$outArray = array_chunk( $inArray, 3, true );
echo '<pre>' . print_r( $outArray, true ) . '</pre>';
/**
Output:
<pre>Array
(
[0] => Array
(
[food_name_1] => Black Coffee
[food_quanty_1] => 1
[food_price_1] => 1000
)
[1] => Array
(
[food_name_2] => Sub Combo
[food_quanty_2] => 2
[food_price_2] => 3000
)
)
</pre>
*/
If I have understood you correctly,
$newdata = array();
for ($i = 1; $i++;) { // Intentionally no condition set.
if (array_key_exists('food_name_' . $i, $arr)) {
$temparray = array();
$temparray['food_name_' . $i] = $arr['food_name_' . $i];
if (array_key_exists('food_quanty_' . $i, $arr)) {
$temparray['food_quanty_' . $i] = $arr['food_quanty_' . $i];
}
if (array_key_exists('food_price_' . $i, $arr)) {
$temparray['food_price_' . $i] = $arr['food_price_' . $i];
}
$newdata[] = $temparray;
} else {
break; // break out of the loop
}
}
echo "<pre>";
print_r($newdata);
echo "</pre>";
die();
Loop through it and build the array index string via variables.
<?php
$arr = [
'tqty' => 9,
'tPrice' => 18700,
'food_name_1' => 'Black Coffee',
'food_quanty_1' => 1,
'food_price_1' => 1000,
'food_name_2' => 'Sub Combo',
'food_quanty_2' => 2,
'food_price_2' => 3000
];
foreach(array("food_name_","food_quanty_","food_price_") as $v){
// replace the set value of 2 here with a count() on the $arr
// and some basic math - IF you are always sure you'll have 3 fields
for($i=0;$i<2;$i++){
$newarr[$i][$v.($i+1)]=$arr[$v.($i+1)];
}
}
print_r($newarr);
?>
Here's a solution that will locate the _x at the end to check its a digit
This solution does not worry about how many non numbered fields you have, or how many fields there are per numbered "row", they are also indexed based on the _x number.
$arr = [
'tqty' => 9,
'tPrice' => 18700,
'food_name_1' => 'Black Coffee',
'food_quanty_1' => 1,
'food_price_1' => 1000,
'food_name_2' => 'Sub Combo',
'food_quanty_2' => 2,
'food_price_2' => 3000
];
$arr2 = array();
foreach( $arr as $key => $value )
{
$explode = explode( '_', $key );
if( ctype_digit( $index = end( $explode ) ) === true)
{
if( isset( $arr2[ $index ] ) === false )
{
$arr2[ $index ] = array();
}
$arr2[ $index ][ substr( $key, 0, strlen( $key ) - 1 - strlen( $index ) ) ] = $value;
}
}
print_r( $arr2 );
Output:
Array
(
[1] => Array
(
[food_name] => Black Coffee
[food_quanty] => 1
[food_price] => 1000
)
[2] => Array
(
[food_name] => Sub Combo
[food_quanty] => 2
[food_price] => 3000
)
)
If you already know that you need always the same indexes from $arr, you can use the array_keys function in order to index the associative array.
Example:
$keys = array_keys($arr);
echo '<br><br>'.$arr[$keys[1]];
Here is a complete example:
$keys = array_keys($arr); #stores the associative keys by index
$arr2 = array();
/* For each array $arr do the following */
$limit = 5; #substitute this with: count($arraylist)
for( $n_array=0; $n_array<limit; $n_array++ ){
$cur_arr = array(); #substitute with your: $arraylist[ $n_array ]
for( $a = 2; $a<count($arr); $a++ ){
$cur_arr[ $keys[$a] ] = $arr[ $keys[$a] ];
}
$arr2[ $n_array ] = $cur_arr;
}
Hope it will be helpful

how to calculate the sum of same array values in PHP

I have an array like this
$estimate[0]=>
'gear' =>'MMG'
'total' => 315
'efforts' => 9
'afh' => 18
$estimate[1]=>
'gear' =>'MMG'
'total' => 400
'efforts' => 2
'afh' => 6
$estimate[2]=>
'gear' =>'BOO'
'total' => 200
'efforts' => 20
'afh' => 16
$estimate[3]=>
'gear' =>'BOB'
'total' => 250
'efforts' => 20
'afh' => 16
I want to calculate the sum of total, efforts and afh in which gear is same and it will be stored in the another array. Following my coding is working when the array (estimate) size is less than 5.
$calculate = array();
for($et=0;$et<count($estimate);):
if($et==0):
$calculate[$et]['gear'] = $estimate[$et]['gear'];
$calculate[$et]['total'] = $estimate[$et]['total'];
$calculate[$et]['efforts'] = $estimate[$et]['efforts'];
$calculate[$et]['afh'] = $estimate[$et]['afh'];
goto loopend;
endif;
for($cet=0;$cet<count($calculate);$cet++):
if($estimate[$et]['gear'] == $calculate[$cet]['gear']):
$calculate[$cet]['total'] = $calculate[$cet]['total'] + $estimate[$et]['total'];
$calculate[$cet]['efforts'] = $calculate[$cet]['efforts'] + $estimate[$et]['efforts'];
$calculate[$cet]['afh'] = $calculate[$cet]['afh'] + $estimate[$et]['afh'];
goto loopend;
endif;
endfor;
$calculate[$et]['gear'] = $estimate[$et]['gear'];
$calculate[$et]['total'] = $estimate[$et]['total'];
$calculate[$et]['efforts'] = $estimate[$et]['efforts'];
$calculate[$et]['afh'] = $estimate[$et]['afh'];
goto loopend;
loopend:$et++;
endfor;
The coding is not working more than many gears. Sometimes it works. I can't find the issues. Please help me to solve the issues.
You might use array_reduce:
$result = array_reduce($estimate, function($carry, $item) {
if (!isset($carry[$item["gear"]])) {
$carry[$item["gear"]] = $item;
return $carry;
}
$carry[$item["gear"]]["total"] += $item["total"];
$carry[$item["gear"]]["efforts"] += $item["efforts"];
$carry[$item["gear"]]["afh"] += $item["afh"];
return $carry;
});
Demo
As per my comment use foreach loop when your array length is not define
Here is your desired code
<?php
$estimate = array(
"0" => array (
"gear" => 35,
"total" => 30,
"efforts" => 39,
"afh" => 39,
),
"1" => array (
"gear" => 35,
"total" => 30,
"efforts" => 39,
"afh" => 39,
),
"2" => array (
"gear" => 35,
"total" => 30,
"efforts" => 39,
"afh" => 39,
),
);
$gear=0;
$total=0;
$efforts=0;
$afh=0;
foreach ($estimate as $key => $value) {
$gear=$gear+$value['gear'];
$total=$gear+$value['total'];
$efforts=$gear+$value['efforts'];
$afh=$gear+$value['afh'];
}
echo "<pre>";
$result = array('gear' => $gear, 'total' => $total,'efforts' => $efforts,'afh' => $afh);
echo "<pre>";
print_r($result);
you can check the result HERE
<?php
$new_arr = array();
$estimate[0] =array(
'gear' =>'MMG',
'total' => 315,
'efforts' => 9,
'afh' => 18
);
$estimate[1]=array(
'gear' =>'MMG',
'total' => 400,
'efforts' => 2,
'afh' => 6,
);
$estimate[2]=array(
'gear' =>'BOO',
'total' => 200,
'efforts' => 20,
'afh' => 16,
);
$estimate[3]=array(
'gear' =>'BOB',
'total' => 250,
'efforts' => 20,
'afh' => 16,
);
foreach ($estimate as $key => $value) {
$new_arr[$value['gear']] = array(
'total' => (isset($new_arr[$value['gear']]['total']) ? ($new_arr[$value['gear']]['total'] + $value['total']) : $value['total'] ),
'efforts' => (isset($new_arr[$value['gear']]['efforts']) ? ($new_arr[$value['gear']]['efforts'] + $value['efforts']) : $value['efforts'] ),
'afh' => (isset($new_arr[$value['gear']]['afh']) ? ($new_arr[$value['gear']]['afh'] + $value['afh']) : $value['afh'] )
);
}
echo "<pre>";print_r($new_arr);

PHP Array Sum By same key value pair needs to Calculated

<?php
error_reporting(E_ALL);
$test_array = Array(Array
(
"pid" => 1,
"encounter" => 20,
"code" => abc,
"fee" => 300.00
),
Array
(
"pid" => 1,
"encounter" => 20,
"code" => abc,
"fee" => 300.00
),
Array
(
"pid" => 2,
"encounter" => 20,
"code" => abc,
"fee" => 80
),
Array
(
"pid" => 3,
"encounter" => 20,
"code" => xyz,
"fee" => 90
),
Array
(
"pid" => 5,
"encounter" => 40,
"code" => xyz,
"fee" => 100
),
Array
(
"pid" => 3,
"encounter" => 40,
"code" => xyz,
"fee" => 100
),
Array
(
"pid" => 2,
"encounter" => 20,
"code" => abc,
"fee" => 80
),
Array
(
"pid" => 1,
"encounter" => 20,
"code" => xyz,
"fee" => 40
));
//Declaration...
$pre_pid = "";
$pre_encounter = "";
$pre_code = "";
$pre_fee = "";
$sum_charges = 0;
/*Foreach loop*/
$i=0;
foreach($test_array as $my_arr){
$pre_pid = $my_arr['pid'];
$pre_encounter = $my_arr['encounter'];
$pre_code = $my_arr['code'];
if($pre_pid == $my_arr['pid'] && $pre_encounter == $my_arr['encounter'] && $pre_code == $my_arr['code']){
echo "FEE-AMOUNT=".$my_arr['fee'];
$sum_charges+=$my_arr['fee'];
echo '<br/>';
}
$i++;
}
//Getting Sum = 1090
//Actual Sum I needed = 710
?>
Hello Friends I am trying above code where i want fee should be calculated of those who having same 3 key value pair.
For Example IF each array 3 key values are same then calculate those fee amount only.
if i understood your problem, you need to sum the fee column everytime the 3 other columns have the same value. I customised your code a bit so you can have the total cost for each of your elements.
//Declaration...
$pre_pid = "";
$pre_encounter = "";
$pre_code = "";
$pre_fee = "";
$sum_charges = 0;
$sum_array = array();
$total_fees = 0;
/*Foreach loop*/
foreach($test_array as &$my_arr){
$pre_pid = $my_arr['pid'];
$pre_encounter = $my_arr['encounter'];
$pre_code = $my_arr['code'];
$pre_fee = $my_arr['fee'];
$fee_ammount = $pre_fee;
$duplicates_check = array();
foreach($test_array as $value) {
if($pre_pid == $value['pid'] && ($pre_encounter != $value['encounter'] || $pre_code != $value['code'])){
$duplicate = false;
foreach($duplicates_check as $duplicate_array) {
if($duplicate_array == $value)
$duplicate =true;
}
if(!$duplicate) {
$fee_ammount += $value['fee'];
$duplicates_check[] = $value;
}
}
}
$my_arr['total_fee'] = $fee_ammount;
if(!isset($sum_array[$my_arr['pid']])) {
$sum_array[$my_arr['pid']] = $my_arr['total_fee'];
echo 'pid => '.$my_arr['pid'].', total fees => '.$my_arr['total_fee'].'<br />';
$total_fees += $my_arr['total_fee'];
}
}
echo 'Total : '.$total_fees;
var_dump($sum_array);

remove duplicate array php

I have script like this
foreach ($onerow as $onekey => $dt ){
$arr = array();
foreach($row as $classkey => $classfoto):
$cek_class_foto = explode("/",$classfoto->name);
if($dt->foto_naam!=$cek_class_foto[1]){
$arr = array($dt->foto_naam);
print_r(array_unique($arr));
}
endforeach;
}
the output like this
Array ( [0] => _b101203.jpg )
Array ( [0] => _b101203.jpg )
my question is, how to remove this duplicates array?
Thank you
You are overwriting $arr for each iteration.
foreach ($onerow as $onekey => $dt ){
$arr = array();
foreach($row as $classkey => $classfoto):
$cek_class_foto = explode("/",$classfoto->name);
if($dt->foto_naam!=$cek_class_foto[1]){
$arr[] =$dt->foto_naam;
}
endforeach;
}
$arr = array_unique($arr);
$array1 = Array
(
'0' => Array
(
'messageId' => 9,
'userId' => 47,
'petId' => 68,
'message' => 'how hello',
'senderId' => 48,
'senderPetId' => 66,
'messageCreateTime' => '2015-07-31 11:44:59'
),
'1' => Array
(
'messageId' => 8,
'userId' => 49,
'petId' => 69,
'message' => 'pppppppppp',
'senderId' => 48,
'senderPetId' => 67,
'messageCreateTime' => '2015-07-31 11:15:16'
),
'2' => Array
(
'messageId' => 6,
'userId' => 48,
'petId' => 67,
'message' => 'gggg',
'senderId' => 49,
'senderPetId' => 69,
'messageCreateTime' => '2015-07-31 11:13:42'
),
'3' => Array
(
'messageId' => 2,
'userId' => 48,
'petId' => 67,
'message' => 'aaaaaaaa',
'senderId' => 47,
'senderPetId' => 68,
'messageCreateTime' => '2015-07-31 11:15:33'
)
);
/* code for removing last duplicate array within result array by KS */
/* matching between : userId, petId, senderId, senderPetId */
$temp_array = array();
$i = 0;
foreach($array1 as $key=>$value)
{
$FLAG = FALSE;
$temp_array = $array1[$key];
if($i==0)
{
$final_array[] = $temp_array;
}
else
{
for($j=0;$j<count($final_array);$j++)
{
if(($final_array[$j]['userId']==$temp_array['userId'] && $final_array[$j]['petId']==$temp_array['petId'] && $final_array[$j]['senderId']==$temp_array['senderId'] && $final_array[$j]['senderPetId']==$temp_array['senderPetId']) ||
($final_array[$j]['userId']==$temp_array['senderId'] && $final_array[$j]['petId']==$temp_array['senderPetId'] && $final_array[$j]['senderId']==$temp_array['userId'] && $final_array[$j]['senderPetId']==$temp_array['petId']))
{
$FLAG = TRUE;
}
}
if($FLAG == FALSE){
$final_array[] = $temp_array;
}
}
$i++;
}
print('<pre>');
print_r($final_array);
enter code here

Get first value from array

I have an PHP array that has saved users steps:
array(
'step_1' => 1,
'step_2' => 1,
'step_3' => 0,
'step_4' => 0,
'step_5' => 0
);
So, my user do step_1, and step_2, but he don't do other steps.
Now, i want to get name of first step that he don't do, it's "step_3" in this example.
But if array looks that:
array(
'step_1' => 1,
'step_2' => 1,
'step_3' => 1,
'step_4' => 1,
'step_5' => 0
);
I want to get "step_5", than i know that user don't do step_5 and i can, for exapmle redirect them to specify page. How can i get it?
You could use array_search()
See In Action
<?php
$array = array(
'step_1' => 1,
'step_2' => 1,
'step_3' => 1,
'step_4' => 0,
'step_5' => 0
);
$key = array_search(0, $array); // $key = step_4;
echo $key;
?>
You can use reset($array);
http://php.net/manual/en/function.reset.php
Return Values
Returns the value of the first array element, or FALSE if the array is empty.
Edit:
You can use array_search(0,$array);
That will return you the key of first found var. (step_5) in your case.
You can try
$step = array(
'step_1' => 1,
'step_2' => 1,
'step_3' => 0,
'step_4' => 0,
'step_5' => 0
);
var_dump(__missing($step));
var_dump($step);
Output
string 'step_3' (length=6)
array
'step_1' => int 1
'step_2' => int 1
'step_3' => int 1
'step_4' => int 0
'step_5' => int 0
Example 2
$step = array(
'step_1' => 1,
'step_2' => 1,
'step_3' => 1,
'step_4' => 1,
'step_5' => 1
);
var_dump(__missing($step));
var_dump($step);
Output
string 'step_1' (length=6)
array
'step_1' => int 1
'step_2' => int 0
'step_3' => int 0
'step_4' => int 0
'step_5' => int 0
Function used
function __missing(&$array) {
$left = array_filter($array, function ($var) {
return ($var == 1) ? false : true;
});
if (! empty($left)) {
$key = key($left);
$array[$key] = 1;
return $key;
} else {
array_walk($array, function (&$var) {
return $var = 0;
});
$key = key($array);
$array[$key] = 1;
return $key;
}
}

Categories