Managing Data Conversions II
Learn how to format numbers and manage the process of data conversion.
We worked to convert our string data back into our original records. We used PHP’s intval
and floatval
functions to convert our strings into PHP data types. Converting our initial data into strings and then from strings back into floats and integers are examples of data conversion. It is relatively rare that data will be stored strictly as-is without any conversion process.
Formatting numbers when converting invoice data
Let’s revisit the idea of converting our invoice data into a fixed-width string format. Still, instead of simply encoding everything as a string, let’s decide that all financial data, such as our total, will be stored with trailing zeroes up to two digits of precision. We can accomplish this by making use of PHP’s number_format
function:
<?php$textData = collect($invoices)->map(function ($invoice) {$totalFormatted = number_format($invoice['total'], 2);return str('')->append(str($invoice['number'])->padLeft(10))->append(str($totalFormatted)->padLeft(10))->append(str($invoice['quantity'])->padLeft(10))->append(str($invoice['pid'])->padLeft(10));})->join('');
Now, when we convert our invoice array into a data string, we see results similar to the following:
1 12.00 5 1 2 32.32 1 2
3 16.00 10 3 4 622.00 4 4
5 77.00 1 5
If we look closely at the data in output in the code snippet above, we can see that we have an exciting opportunity. Because we have decided that all currency values will always be stored with up to two digits of precision, it has become redundant to store the actual decimal separator. If we were to remove it, our storage field would be able to contain an additional digit that was previously being used by the separator character. We can also do this by slightly modifying our existing implementation to let PHP know we do not want any separator characters. We achieve this by supplying an empty string for both the decimal and thousandths separator arguments:
<?php$textData = collect($invoices)->map(function ($invoice) {$totalFormatted = number_format($invoice['total'], 2, '', '');return str('')->append(str($invoice['number'])->padLeft(10))->append(str($totalFormatted)->padLeft(10))->append(str($invoice['quantity'])->padLeft(10))->append(str($invoice['pid'])->padLeft(10));})->join('');
Encoding our data using the modifications in the code above, our output would now be:
1 1200 5 1 2 3232 1
2 3 1600 10 3 4 62200 4
4 5 7700 1 5
Our generated data string in the code snippet below is still the same length as before, so our total record calculations will still be correct. However, our changes will present a new problem when attempting to retrieve the total currency amount of each invoice. Specifically, the challenge is that each total now looks similar to:
3232
There are actually several different approaches to solving this problem. If we look carefully at our new numbers, we can see that all we have actually done by removing the decimal place is to multiply the original total by 100. We can make this assumption since we know that our invoice totals will always be ...