I have a function that counts the number of points for each letter. I want her to count the points for each word. See this is my code:
function getValue() {
$letter = $this->getName(); // String from FORM
// Switch looks at a letter and assigns the value points for that letter
switch(true){
case($letter == 'a'||$letter == 'e'||$letter == 'i'||$letter == 'o'||$letter == 'u'||$letter == 'l'||$letter == 'n'||$letter == 's'||$letter == 't'||$letter == 'r'):
return 1;
case($letter == 'd'||$letter == 'g'):
return 2;
case($letter == 'b'||$letter == 'c'||$letter == 'm'||$letter == 'p'):
return 3;
case($letter == 'f'||$letter == 'h'||$letter == 'v'||$letter == 'w'||$letter == 'y'):
return 4;
case($letter == 'k'):
return 5;
case($letter == 'j'||$letter == 'x'):
return 8;
case($letter == 'q'||$letter == 'z'):
return 10;
default:
return 0;
}
}
function makeWordsPoint() {
$total_word_points = 0;
$words = $this->word_for_letters;
foreach ($words as $word) {
$total_word_points = $word->getValue();
}
echo $word . "=" . $total_word_points
}
How I can do it? Thanks for help
EDIT:
Okey, look now. There is my two classes Word and Letter
<?php
class Word
{
private $word;
private $words_with_points = array();
function __construct($user_letters)
{
$this->word = $user_letters;
// creates array of object word for letters
$this->word_for_letters = $this->makeWordForLetters();
// creates array of letter objects for the word
$this->words_with_points = $this->makeWordsWithPoints();
}
function makeWordForLetters()
{
$word_objects = array();
$word = $this->getWord();
$file = file_get_contents( __DIR__."/../src/dictionary.txt");
$items = explode("\n", $file);
$letters = str_split($word);
foreach ($items as $item) {
$list = $letters;
// remove the original word (once)
$thisItem = preg_replace("/$word/", '', $item, 1);
for ($i = 0; $i < strlen($thisItem); $i++) {
$index = array_search($thisItem[$i], $list);
if ($index === false) {
continue 2; // letter not available
}
unset($list[$index]); // remove the letter from the list
}
array_push($word_objects, $item);
}
return $word_objects; // passed!
}
function makeWordsWithPoints()
{
$word = $this->makeWordForLetters();
$letter_objects = array();
foreach ($word as $character) {
array_push($letter_objects, new Letter($character));
}
return $letter_objects;
}
function getWord()
{
return $this->word;
}
function getWordForLetters()
{
return $this->word_for_letters;
}
function getWordsWithPoints()
{
return $this->words_with_points;
}
}
?>
<?php
class Letter
{
private $name;
private $value;
function __construct($letter)
{
$letter = strtolower($letter);
$this->name = $letter;
$this->value = $this->setValue();
}
function getName()
{
return $this->name;
}
function getValue()
{
return $this->value;
}
function setValue()
{
$letter = $this->getName();
switch(true){
case($letter == 'a'||$letter == 'e'||$letter == 'i'||$letter == 'o'||$letter == 'u'||$letter == 'l'||$letter == 'n'||$letter == 's'||$letter == 't'||$letter == 'r'):
return 1;
case($letter == 'd'||$letter == 'g'):
return 2;
case($letter == 'b'||$letter == 'c'||$letter == 'm'||$letter == 'p'):
return 3;
case($letter == 'f'||$letter == 'h'||$letter == 'v'||$letter == 'w'||$letter == 'y'):
return 4;
case($letter == 'k'):
return 5;
case($letter == 'j'||$letter == 'x'):
return 8;
case($letter == 'q'||$letter == 'z'):
return 10;
default:
return 0;
}
}
}
?>
And now when I write in now letters like this: loso function makeWordForLetters() search in my array correctly words for this letters and I display this words with points by makeWordsWithPoint like this:
l - 1
lo - 0
loo - 0
loos - 0
los - 0
oslo - 0
s - 1
solo - 0
But as you can see the score is incorrect because it displays the result for a single letter and not for a word.
How can I solve this problem?
take it as string, then use preg_split function, count new array length.eg:
$string="php教程#php入门:教程#字符串:多分隔符#字符串:拆分#数组";
$arr = preg_split("/(#|:)/",$string);
print_r($arr);
Try this code instead. I think it's cleaner.
<?php
// set the score of each char into array
const SCORES = [
// 1
'a'=> 1,
'e' => 1,
'i' => 1,
'o' => 1,
'u' => 1,
'l' => 1,
'n' => 1,
's' => 1,
't' => 1,
'r' => 1,
// 2
'd'=> 2,
'g'=> 2,
// 3
'b'=> 3,
'c'=> 3,
'm'=> 3,
'p'=> 3,
// 4
'f'=> 4,
'h'=> 4,
'v'=> 4,
'w'=> 4,
'y'=> 4,
// 5
'k'=> 5,
// 8
'j'=> 8,
'x'=> 8,
// 10
'q'=> 10,
'z'=> 10,
];
$word = 'abcdef'; // get the string from the request here
# print_r($word);
$chars = str_split($word); // split string into array of chars
# print_r($chars);
$scores = array_map(function($char) { // create a scores array that convert char into value
return SCORES[strtolower($char)] ?? 0; // get the score of each char and set to the array, if not exist set to 0
}, $chars);
# print_r($scores);
$totalScore = array_sum($scores); // get the sum of the scores
echo $word . "=" . $totalScore;
Let me know if you have any question.
how can I change the colors of ONLY decimals of a number in PHP?
this is my function for formatting numbers
function formatNumber($input, $decimals = 'auto', $prefix = '', $suffix = '') {
$input = floatval($input);
$absInput = abs($input);
if ($decimals === 'auto') {
if ($absInput >= 0.01) {
$decimals = 2;
} elseif (0.0001 <= $absInput && $absInput < 0.01) {
$decimals = 4;
} elseif (0.000001 <= $absInput && $absInput < 0.0001) {
$decimals = 6;
} elseif ($absInput < 0.000001) {
$decimals = 8;
}
}
if($input>1000000000000000){
$result = ROUND(($input/1000000000000000),2).' TH ';
}elseif($input>1000000000000){
$result = ROUND(($input/1000000000000),2).' T ';
}elseif($input>1000000000){
$result = ROUND(($input/1000000000),2).' B ';
}elseif($input>1000000) {
$result = ROUND(($input / 1000000), 2) . ' M ';
} else {
$result = number_format($input, $decimals, config('decimal-separator','.'), config('thousand-separator', ',')) ;
}
return ($prefix ? $prefix : '') . $result. ($suffix ? $suffix : '');
}
and I use it like that
<?php echo formatNumber($chart['assist'], 2)?>
i want my decimals with a different color... can i use css there or add classes?
Here is an example of what I meant in my comment by manipulate the string:
<?php
$n = 123.456;
$whole = floor($n); // 123
$fraction = $n - $whole; // .456
//echo str_replace('.', '<span class="colorme">.</span>', $n);
echo $whole . '<span class="colorme">.</span>' . substr($fraction, strpos($fraction, '.')+1);
//Simply do a string replace on the decimal point.
UPDATED break out parts, concatenate.
A client side approach with Javascript (with some jQuery) would be something like:
$('#myDiv').each(function () {
$(this).html($(this).html().replace(/\./g, '<span class="colorme">.</span>'));
//or decimal point and decimal number part...
$(this).html($(this).html().replace(/\.([0-9]+)/g, '<span class="colorme">.$1</span>'));
});
Remember that other locales don't always use . for divider.
So with your existing code, you could do something like:
$dec_point = config('decimal-separator','.');
$wrapped_dec_point = "<span class='dec_point'>{$dec_point}</span>";
$result = number_format($input, $decimals, $wrapped_dec_point, config('thousand-separator', ',')) ;
and then of course, for your CSS, you would just need
.dec_point {
color: magenta;
}
Here is shorter solution
$n = 123.456;
$nums = explode(".",$n);
echo $nums[0] . '<span class="colorme">.' . $nums[1] . '</span>';
I created this function to converting numbers to words. And how I can convert words to number using this my function:
Simple function code:
$array = array("1"=>"ЯК","2"=>"ДУ","3"=>"СЕ","4"=>"ЧОР","5"=>"ПАНҶ","6"=>"ШАШ","7"=>"ҲАФТ","8"=>"ХАШТ","9"=>"НӮҲ","0"=>"НОЛ","10"=>"ДАҲ","20"=>"БИСТ","30"=>"СИ","40"=>"ЧИЛ","50"=>"ПАНҶОҲ","60"=>"ШАСТ","70"=>"ҲАФТОД","80"=>"ХАШТОД","90"=>"НАВАД","100"=>"САД");
$n = "98"; // Input number to converting
if($n < 10 && $n > -1){
echo $array[$n];
}
if($n == 10 OR $n == 20 OR $n == 30 OR $n == 40 OR $n == 50 OR $n == 60 OR $n == 70 OR $n == 80 OR $n == 90 OR $n == 100){
echo $array[$n];
}
if(mb_strlen($n) == 2 && $n[1] != 0)
{
$d = $n[0]."0";
echo "$array[$d]У ".$array[$n[1]];
}
My function so far converts the number to one hundred. How can I now convert text to a number using the answer of my function?
So, as #WillParky93 assumed, your input has spaces between words.
<?php
mb_internal_encoding("UTF-8");//For testing purposes
$array = array("1"=>"ЯК","2"=>"ДУ","3"=>"СЕ","4"=>"ЧОР","5"=>"ПАНҶ","6"=>"ШАШ","7"=>"ҲАФТ","8"=>"ХАШТ","9"=>"НӮҲ","0"=>"НОЛ","10"=>"ДАҲ","20"=>"БИСТ","30"=>"СИ","40"=>"ЧИЛ","50"=>"ПАНҶОҲ","60"=>"ШАСТ","70"=>"ҲАФТОД","80"=>"ХАШТОД","90"=>"НАВАД","100"=>"САД");
$postfixes = array("3" => "ВУ");
$n = "98"; // Input number to converting
$res = "";
//I also optimized your conversion of numbers to words
if($n > 0 && ($n < 10 || $n%10 == 0))
{
$res = $array[$n];
}
if($n > 10 && $n < 100 && $n%10 != 0)
{
$d = intval(($n/10));
$sd = $n%10;
$ending = isset($postfixes[$d]) ? $postfixes[$d] : "У";
$res = ($array[$d * 10]).$ending." ".$array[$sd];
}
echo $res;
echo "\n<br/>";
$splitted = explode(" ", $res);
//According to your example, you use only numerals that less than 100
//So, to simplify your task(btw, according to Google, the language is tajik
//and I don't know the rules of building numerals in this language)
if(sizeof($splitted) == 1) {
echo array_search($splitted[0], $array);
}
else if(sizeof($splitted) == 2) {
$first = $splitted[0];
$first_length = mb_strlen($first);
if(mb_substr($first, $first_length - 2) == "ВУ")
{
$first = mb_substr($first, 0, $first_length - 2);
}
else
{
$first = mb_substr($splitted[0], 0, $first_length - 1);
}
$second = $splitted[1];
echo (array_search($first, $array) + array_search($second, $array));
}
You didn't specify the input specs but I took the assumption you want it with a space between the words.
//get our input=>"522"
$input = "ПАНҶ САД БИСТ ДУ";
//split it up
$split = explode(" ", $input);
//start out output
$c = 0;
//set history
$history = "";
//loop the words
foreach($split as &$s){
$res = search($s);
//If number is 9 or less, we are going to check if it's with a number
//bigger than or equal to 100, if it is. We multiply them together
//else, we just add them.
if((($res = search($s)) <=9) ){
//get the next number in the array
$next = next($split);
//if the number is >100. set $nextres
if( ($nextres = search($next)) >= 100){
//I.E. $c = 5 * 100 = 500
$c = $nextres * $res;
//set the history so we skip over it next run
$history = $next;
}else{
//Single digit on its own
$c += $res;
}
}elseif($s != $history){
$c += $res;
}
}
//output the result
echo $c;
function search($s){
global $array;
if(!$res = array_search($s, $array)){
//grab the string length
$max = strlen($s);
//remove one character at a time until we find a match
for($i=0;$i<$max; $i++ ){
if($res = array_search(mb_substr($s, 0, -$i),$array)){
//stop the loop
$i = $max;
}
}
}
return $res;
}
Output is 522.
So I have a website video like Youtube and the problem is that
I want the number like this exemple :
1,234 views -> 1,2 K
So this is the code
function pm_number_format($number, $decimals = 0, $dec_point = '.', $thousands_sep = ',')
{
return number_format($number, $decimals, $dec_point, $thousands_sep);
}
function pm_compact_number_format($number)
{
if ($number < 10000)
{
return pm_number_format($number);
}
$d = $number < 1000000 ? 1000 : 1000000;
$f = round($number / $d, 1);
return pm_number_format($f, $f - intval($f) ? 1 : 0) . ($d == 1000 ? 'k' : 'M');
}
Just change your if condition and remove 1x zero, so from this:
if ($number < 10000) {
return pm_number_format($number);
}
to this:
if ($number < 1000) {
return pm_number_format($number);
}
Input:
1
12
123
1234
12345
123456
1234567
12345678
123456789
Output:
1
12
123
1.2K //<--See output as you wanted
12.3K
123.5K
1.2M
12.3M
123.5M
EDIT:
Here is my code i modify(like i described up above) and used to produce the output:
<?php
function pm_number_format($number, $decimals = 0, $dec_point = '.', $thousands_sep = ',') {
return number_format($number, $decimals, $dec_point, $thousands_sep);
}
function pm_compact_number_format($number) {
if ($number < 1000)
return pm_number_format($number);
$d = $number < 1000000 ? 1000 : 1000000;
$f = round($number / $d, 1);
return pm_number_format($f, $f - intval($f) ? 1 : 0) . ($d == 1000 ? 'k' : 'M');
}
$number = "";
foreach(range(1,10) as $value) {
$number .= $value;
echo pm_compact_number_format($number) . "<br />";
}
?>
I have this number:
$double = '21.188624';
After using number_format($double, 2, ',', ' ') I get:
21,19
But what I want is:
21,18
Any ideea how can I make this work?
Thank you.
number_format will always do that, your only solution is to feed it something different:
$number = intval(($number*100))/100;
Or:
$number = floor(($number*100))/100;
I know that this an old question, but it still actual :) .
How about this function?
function numberFormatPrecision($number, $precision = 2, $separator = '.')
{
$numberParts = explode($separator, $number);
$response = $numberParts[0];
if (count($numberParts)>1 && $precision > 0) {
$response .= $separator;
$response .= substr($numberParts[1], 0, $precision);
}
return $response;
}
Usage:
// numbers test
numberFormatPrecision(19, 2, '.'); // expected 19 return 19
numberFormatPrecision(19.1, 2, '.'); //expected 19.1 return 19.1
numberFormatPrecision(19.123456, 2, '.'); //expected 19.12 return 19.12
numberFormatPrecision(19.123456, 0, '.'); //expected 19 return 19
// negative numbers test
numberFormatPrecision(-19, 2, '.'); // expected -19 return -19
numberFormatPrecision(-19.1, 2, '.'); //expected -19.1 return -19.1
numberFormatPrecision(-19.123456, 2, '.'); //expected -19.12 return -19.12
numberFormatPrecision(-19.123456, 0, '.'); //expected -19 return -19
// precision test
numberFormatPrecision(-19.123456, 4, '.'); //expected -19.1234 return -19.1234
// separator test
numberFormatPrecision('-19,123456', 3, ','); //expected -19,123 return -19,123 -- comma separator
Function (only precision):
function numberPrecision($number, $decimals = 0)
{
$negation = ($number < 0) ? (-1) : 1;
$coefficient = 10 ** $decimals;
return $negation * floor((string)(abs($number) * $coefficient)) / $coefficient;
}
Examples:
numberPrecision(2557.9999, 2); // returns 2557.99
numberPrecision(2557.9999, 10); // returns 2557.9999
numberPrecision(2557.9999, 0); // returns 2557
numberPrecision(2557.9999, -2); // returns 2500
numberPrecision(2557.9999, -10); // returns 0
numberPrecision(-2557.9999, 2); // returns -2557.99
numberPrecision(-2557.9999, 10); // returns -2557.9999
numberPrecision(-2557.9999, 0); // returns -2557
numberPrecision(-2557.9999, -2); // returns -2500
numberPrecision(-2557.9999, -10); // returns 0
Function (full functionality):
function numberFormat($number, $decimals = 0, $decPoint = '.' , $thousandsSep = ',')
{
$negation = ($number < 0) ? (-1) : 1;
$coefficient = 10 ** $decimals;
$number = $negation * floor((string)(abs($number) * $coefficient)) / $coefficient;
return number_format($number, $decimals, $decPoint, $thousandsSep);
}
Examples:
numberFormat(2557.9999, 2, ',', ' '); // returns 2 557,99
numberFormat(2557.9999, 10, ',', ' '); // returns 2 557,9999000000
numberFormat(2557.9999, 0, ',', ' '); // returns 2 557
numberFormat(2557.9999, -2, ',', ' '); // returns 2 500
numberFormat(2557.9999, -10, ',', ' '); // returns 0
numberFormat(-2557.9999, 2, ',', ' '); // returns -2 557,99
numberFormat(-2557.9999, 10, ',', ' '); // returns -2 557,9999000000
numberFormat(-2557.9999, 0, ',', ' '); // returns -2 557
numberFormat(-2557.9999, -2, ',', ' '); // returns -2 500
numberFormat(-2557.9999, -10, ',', ' '); // returns 0
floor($double*100)/100
I use this function:
function cutNum($num, $precision = 2) {
return floor($num) . substr(str_replace(floor($num), '', $num), 0, $precision + 1);
}
Usage examples:
cutNum(5) //returns 5
cutNum(5.6789) //returns 5.67 (default precision is two decimals)
cutNum(5.6789, 3) //returns 5.678
cutNum(5.6789, 10) //returns 5.6789
cutNum(5.6789, 0) //returns 5. (!don't use with zero as second argument: use floor instead!)
Explanation: here you have the same function, just more verbose to help understanding its behaviour:
function cutNum($num, $precision = 2) {
$integerPart = floor($num);
$decimalPart = str_replace($integerPart, '', $num);
$trimmedDecimal = substr($decimalPart, 0, $precision + 1);
return $integerPart . $trimmedDecimal;
}
Use the PHP native function bcdiv.
function numberFormat($number, $decimals = 2, $sep = ".", $k = ","){
$number = bcdiv($number, 1, $decimals); // Truncate decimals without rounding
return number_format($number, $decimals, $sep, $k); // Format the number
}
See this answer for more details.
**Number without round**
$double = '21.188624';
echo intval($double).'.'.substr(end(explode('.',$double)),0,2);
**Output** 21.18
In case you don't care for what comes behind the decimal point, you can cast the float as an int to avoid rounding:
$float = 2.8;
echo (int) $float; // outputs '2'
$double = '21.188624';
$teX = explode('.', $double);
if(isset($teX[1])){
$de = substr($teX[1], 0, 2);
$final = $teX[0].'.'.$de;
$final = (float) $final;
}else{
$final = $double;
}
final will be 21.18
In case you need 2 fixed decimal places, you can try this!
#Dima's solution is working for me, but it prints "19.90" as "19.9" so I made some changes as follows:
<?php
function numberPrecision($number, $decimals = 0)
{
$negation = ($number < 0) ? (-1) : 1;
$coefficient = 10 ** $decimals;
$result = $negation * floor((string)(abs($number) * $coefficient)) / $coefficient;
$arr = explode(".", $result);
$num = $arr[0];
if(empty($arr[1]))
$num .= ".00";
else if(strlen($arr[1]) == 1)
$num .= "." . $arr[1] . "0";
else
$num .= ".". $arr[1];
return $num;
}
echo numberPrecision(19.90,2); // 19.90
So, what I did is, I just break the result into two parts with explode function. and convert the result into a string with concatenation!
public function numberFormatPrecision( $number, $separator = '.', $format = 2 ){
$response = '';
$brokenNumber = explode( $separator, $number );
$response = $brokenNumber[0] . $separator;
$brokenBackNumber = str_split($brokenNumber[1]);
if( $format < count($brokenBackNumber) ){
for( $i = 1; $i <= $format; $i++ )
$response .= $brokenBackNumber[$i];
}
return $response;
}
$finalCommishParts = explode('.',$commission);
$commisshSuffix = (isset($finalCommishParts[1])?substr($finalCommishParts[1],0,2):'00');
$finalCommish = $finalCommishParts[0].'.'.$commisshSuffix;
The faster way as exploding(building arrays) is to do it with string commands like this:
$number = ABC.EDFG;
$precision = substr($number, strpos($number, '.'), 3); // 3 because . plus 2 precision
$new_number = substr($number, 0, strpos($number, '.')).$precision;
The result ist ABC.ED in this case because of 2 precision
If you want more precision just change the 3 to 4 or X to have X-1 precision
Cheers
Javascript Version
function numberFormat($number, $decimals = 0, $decPoint = '.' , $thousandsSep = ',')
{
return number_format((Math.floor($number * 100) / 100).toFixed($decimals), $decimals, $decPoint, $thousandsSep );
}
// https://locutus.io/php/strings/number_format/
function number_format(number, decimals, decPoint, thousandsSep) {
if(decimals === 'undefined') decimals = 2;
number = (number + '').replace(/[^0-9+\-Ee.]/g, '')
const n = !isFinite(+number) ? 0 : +number
const prec = !isFinite(+decimals) ? 0 : Math.abs(decimals)
const sep = (typeof thousandsSep === 'undefined') ? ',' : thousandsSep
const dec = (typeof decPoint === 'undefined') ? '.' : decPoint
let s = ''
const toFixedFix = function (n, prec) {
if (('' + n).indexOf('e') === -1) {
return +(Math.round(n + 'e+' + prec) + 'e-' + prec)
} else {
const arr = ('' + n).split('e')
let sig = ''
if (+arr[1] + prec > 0) {
sig = '+'
}
return (+(Math.round(+arr[0] + 'e' + sig + (+arr[1] + prec)) + 'e-' + prec)).toFixed(prec)
}
}
// #todo: for IE parseFloat(0.55).toFixed(0) = 0;
s = (prec ? toFixedFix(n, prec).toString() : '' + Math.round(n)).split('.')
if (s[0].length > 3) {
s[0] = s[0].replace(/\B(?=(?:\d{3})+(?!\d))/g, sep)
}
if ((s[1] || '').length < prec) {
s[1] = s[1] || ''
s[1] += new Array(prec - s[1].length + 1).join('0')
}
return s.join(dec)
}
$number = 2.278;
echo new_number_format($number,1);
//result: 2.2
function new_number_format($number,$decimal)
{
//explode the number with the delimiter of dot(.) and get the whole number in index 0 and the decimal in index 1
$num = explode('.',$number);
//if the decimal is equal to zero
//take note that we can't split the zero value only and it will return Undefined offset if we split the zero only
//for example: rating_format(2.0,1); the result will be 2. the zero is gone because of the Undefined offset
//the solution of this problem is this condition below
if($num[1] == 0)
{
$final_decimal = '';
$i=0;
//loop the decimal so that we can display depend on how many decimal that you want to display
while($i<$decimal){
$final_decimal .= 0;
$i++;
}
}
//if the decimal is not zero
else
{
$dec = str_split($num[1]); //split the decimal and get the value using the array index
$i=0;
$final_decimal = '';
//loop the decimal so that we can display depend on how many decimal that you want to display
while($i<$decimal){
$final_decimal .= $dec[$i];
$i++;
}
}
$new_number= $num[0].'.'.$final_decimal;//combine the result with final decimal
return $new_number; //return the final output
}
thanks for your help Dima!!! My function
private function number_format(float $num, int $decimals = 0, ?string $decimal_separator = ',', ?string $thousands_separator = '.'){
/**
* Formatea un numero como number_format sin redondear hacia arriba, trunca el resultado
* #access private
* #param string num - Numero de va a ser formateado
* #param int decimals - Posiciones Decimales
* #param string|null $decimal_separator — [opcional]
* #param string|null $thousands_separator — [opcional]
* #return string — Version de numero formateado.
*/
$negation = ($num < 0) ? (-1) : 1;
$coefficient = 10 ** $decimals;
$number = $negation * floor((string)(abs($num) * $coefficient)) / $coefficient;
return number_format($number, $decimals, $decimal_separator, $thousands_separator);
}
for use it
echo $this->number_format(24996.46783, 3, ',', '.'); //24.996,467
use this function:
function number_format_unlimited_precision($number,$decimal = '.')
{
$broken_number = explode($decimal,$number);
return number_format($broken_number[0]).$decimal.$broken_number[1]);
}
In Case you have small float values you can use number_format function this way.
$number = 21.23;
echo number_format($number, 2, '.', ',') ); // 21.23
In case you have you have long decimal number then also it will format number this way
$number = 201541.23;
echo number_format($number, 2, '.', ',') ); // 201,541.23