2

I've tried to write a function that will take an array of different amounts and align the decimal places, by adding the appropriate amount of   to each number with a lesser length than the number with longest length.

It seems pretty long though, and I wonder if anyone has some insight on how I could make is shorter and more efficient.

$arr = array(12, 34.233, .23, 44, 24334, 234);

function align_decimal ($arr) {
    $long = 0;
    $len = 0;


    foreach ( $arr as &$i ){
        //change array elements to string
        (string)$i;

        //if there is no decimal, add '.00'
        //if there is a decimal, add '00'
        //ensures that there are always at least two zeros after the decimal
        if ( strrpos( $i, "." ) === false  ) {
            $i .= ".00";
        } else {
            $i .= "00";
        }

        //find the decimal
        $dec = strrpos( $i, "." );

        //ensure there are only two decimals
        //$dec+3 is the decimal plus two characters
        $i = substr_replace($i, "", $dec+3);

        //if $i is longer than $long, set $long to $i
        if ( strlen($i) >= strlen($long) ) {
            $long = $i;
        }

    }

    //locate the decimal in the longest string
    $long_dec = strrpos( $long, "." );

    foreach ( $arr as &$i ) {

        //difference between $i and $long position of the decimal
        $z = ( $long_dec - strrpos( $i, "." ) );
        $c = 0;
        while ( $c <= $z  )  {
            //add a &nbsp; for each number of characters 
            //between the two decimal locations
            $i = "&nbsp;" . $i;
            $c++;
        }

    }

    return $arr;
}

it works okkaaay... just seems really verbose. I'm sure there are a million ways to make it much shorter and more professional. Thanks for any ideas!

4

3 回答 3

2

Code:

$array = array(12, 34.233, .23, 44, 24334, 234);;
foreach($array as $value) $formatted[] = number_format($value, 2, '.', '');
$length = max(array_map('strlen', $formatted));
foreach($formatted as $value)
{
    echo str_repeat("&nbsp;",$length-strlen($value)).$value."<br>";
}

Output:

&nbsp;&nbsp;&nbsp;12.00<br>
&nbsp;&nbsp;&nbsp;34.23<br>
&nbsp;&nbsp;&nbsp;&nbsp;0.23<br>
&nbsp;&nbsp;&nbsp;44.00<br>
24334.00<br>
&nbsp;&nbsp;234.00<br>

Rendered by browser:

   12.00
   34.23
    0.23
   44.00
24334.00
  234.00
于 2012-07-05T15:49:12.447 回答
2

Is using a space a requirement for the display? If you don't mind having "30" coming out as "30.000" you could use the number_format to do most of the work for you, after you figured out the max number of decimal places to use.

$item = "40";
$len = 10;
$temp = number_format($item,$len);
echo $temp;

Another would be to use sprintf to format:

$item = "40";
$len = 10;
$temp = sprintf("%-{$len}s", $item);
$temp = str_replace(' ', '&nbsp;',$temp);
echo $temp;
于 2012-07-05T15:49:19.587 回答
1

Have you considered using HTML elements alongside CSS alignment to do this for you?

For instance:

<div style="display:inline-block; text-align:right;">$10.00<br />$1234.56<div>

This would ease the issue of using spaces to manually adjust the alignment. Since you're aligning to the right and there are two decimal places, the decimals will line up as you wish. You could also do this using a <table> and in both scenarios, you're able to simply retrieve the full value through JS if need be.

Lastly, using spaces assumes you're using a fixed-width font which may not necessarily be the case. CSS alignment allows you to handle this much more eloquently.

于 2012-07-05T15:48:48.413 回答