У меня есть база данных с столбцом, содержащим множество чисел, написанных в «стенографическом» виде, например:
5 тыс. За 5000
86,6 тыс. За 86 600
4,1 м для 4 100 000
1,2 млрд. За 1 200 000 000
Я бы хотел сделать некоторые вычисления с этими числами для интерфейса PHP, но для этого мне нужно преобразовать их в действительные целые числа. Как я могу сделать это с помощью PHP?
Что-то вроде:
switch (strtolower(substr($input, -1))) { case 'k': $input*=1000; break; // similarly for m, M, b, B. }
Предполагая, что ваши данные хорошо отформатированы. Если потребуется больше проверки, например:
if (!preg_match('/^\d+(?:\.\d+)?[mbk]$/i',$input)) { // $input is not a valid format. }
Если это ваш формат данных и является последовательным. вы можете написать свою собственную функцию. создайте карту суффикса для множителя .. "k" => 1000, "m" => 100000
и умножить целочисленное значение на значение множителя. Вот решение на основе sscanf: http://codepad.org/FjwBbx1D
<?php $map = array("k" => 1000,"m" => 1000000,"b" => 1000000000); $money = "86.6k"; list($value,$suffix) = sscanf($money, "%f%s"); $final = $value*$map[$suffix]; var_dump($final); ?>
И вот простой лайнер:
<?php $money = "86.6k"; $value = substr($money,0,-1)*pow(10,strpos("---k--m--b",substr($money,-1))) ; var_dump($value); ?>
Я думаю, что эта функция намного чище и эффективнее
function formatNumberAbbreviation($number) { $abbrevs = array(12 => "T", 9 => "B", 6 => "M", 3 => "K", 0 => ""); foreach($abbrevs as $exponent => $abbrev) { if($number >= pow(10, $exponent)) { return intval($number / pow(10, $exponent)) . $abbrev; } } }
Он достигает триллиона, вы можете добавить более высокие значения, если хотите, но убедитесь, что вы помещаете их в массив от наивысшего до самого низкого.
Существует функция PHP, ini_get()
на странице руководства ini_get()
(на самой странице руководства, а не в примечаниях пользователей) , которая делает именно это.
Цитата:
function return_bytes($val) { $val = trim($val); $last = strtolower($val[strlen($val)-1]); switch($last) { // The 'G' modifier is available since PHP 5.1.0 case 'g': $val *= 1024; case 'm': $val *= 1024; case 'k': $val *= 1024; } return $val; }
Обратите внимание, что эта функция используется, чтобы показать, как преобразовать значения сокращенного байта в значения целочисленных байтов и, как таковые, считает, что 1k = 1024; а не 1000.
Логика для реализации, итерация по всем символам, и когда вы найдете символ (а не цифру), просто сохраните индекс. Теперь разделите это на две части: цифровое значение и характер. Теперь создайте функцию, которая возвращает значение переданного символа. например. getValueOf ('M') = 1000000 И затем, наконец, сделайте это числовое значение * getValueOf ('M') Вот и все. Примечание. В ваших числовых значениях есть запятые, поэтому также str_replace (',', '', числовое значение), а затем преобразование в int
$string = '5k'; // or whatever $suffix = strspn($string, '.0123456789'); $value = doubleval(substr($string, 0, $suffix)) if($suffix < strlen($string)) { switch($string[$suffix]) { case 'k': $value *= 1000; break; case 'm': $value *= 1000000; break; case 'b': $value *= 1000000000; break; } } echo number_format($value);