1

我经常需要列出用逗号、空格或标点符号分隔的项目,地址是一个典型的例子(这对于地址来说是多余的,只是为了举例!):

echo "L$level, $unit/$num $street, $suburb, $state $postcode, $country.";
//ouput: L2, 1/123 Cool St, Funky Town, ABC 2000, Australia.

听起来很简单,有没有一种简单的方法可以“有条件地”仅在变量存在时在变量之间添加自定义分隔符?是否需要检查是否设置了每个变量?因此,使用上述内容,另一个细节较少的地址可能会输出如下内容:

//L, / Cool St, , ABC , .

一种稍微费力的检查方法是查看是否设置了每个变量并显示标点符号。

if($level){ echo "L$level, "; }
if($unit){ echo "$unit"; }
if($unit && $street){ echo "/"; }
if($street){ echo "$street, "; }
if($suburb){ echo "$suburb, "; }
//etc...

最好有一个可以自动执行所有剥离/格式化等的功能:

somefunction("$unit/$num $street, $suburb, $state $postcode, $country.");

另一个例子是一个简单的 csv 列表。我想输出以逗号分隔的 x 项:

for($i=0; $i=<5; $i++;){ echo "$i,"; }
//output: 1,2,3,4,5,

例如,在循环中,确定数组的最后一项或满足循环条件以在列表末尾不包含逗号的最佳方法是什么?我读过的一个很长的方法是在一个项目之前放一个逗号,除了第一个条目,比如:

$firstItem = true; //first item shouldn't have comma
for($i=0; $i=<5; $i++;){
  if(!$firstItem){ echo ","; }
  echo "$i";
  $firstItem = false;
}
4

8 回答 8

3

对于您的第一个示例,您可以将数组与一些数组方法结合使用来获得所需的结果。例如:

echo join(', ', array_filter(array("L$level", join(' ', array_filter(array(join('/', array_filter(array($unit, $num))), $street))), $suburb, join(' ', array_filter(array($state, $postcode))), $country))) . '.';

这个单行代码读起来相当复杂,所以总是可以将数组、array_filter 和 join 调用包装到一个单独的方法中,并使用它:

function merge($delimiter)
{
    $args = func_get_args();
    array_shift($args);
    return join($delimiter, array_filter($args));
}

echo merge(', ', "L$level", merge(' ', merge('/', $unit, $num), $street), $suburb, merge(' ', $state, $postcode), $country) . '.';

您需要调用 array_filter 来删除空条目,否则仍会打印出分隔符。

对于第二个示例,将项目添加到数组中,然后使用 join 插入分隔符:

$arr = array();
for($i=0; $i=<5; $i++)
{
    $arr[] = $i;
}
echo(join(',', $arr));
于 2009-04-15T14:15:52.467 回答
1

虽然 Phillip 的回答解决了您的问题,但我想用Eric Lippert的以下博客文章来补充它。尽管他的讨论是在 c# 中进行的,但它适用于任何编程语言。

于 2009-04-15T13:56:33.090 回答
1

您的第二个问题有一个简单的解决方案:

for($i=0; $i<=5; $i++)
    $o .= "$i,";
echo chop($o, ',');
于 2009-04-15T14:02:56.193 回答
1

Philip 的解决方案在处理数组时可能是最好的(如果您不必过滤掉空值),但如果您不能使用数组函数——例如,在处理从返回的查询结果时——mysqli_fetch_object()那么一种解决方案只是一个简单的 if 语句:

$list = '';
$row=mysqli_fetch_object($result);
do {
    $list .= (empty($list) ? $row->col : ", {$row->col}");
} while ($row=mysqli_fetch_object($result));

或者,或者:

do {
    if (isset($list)) {
        $list .= ", {$row->col}";
    } else $list = $row->col;
} while ($row=mysqli_fetch_object($result));

要构建一个列表并过滤掉空值,我会编写一个自定义函数:

function makeList() {
    $args = array_filter(func_get_args()); // as per Jon Benedicto's answer
    foreach ($args as $item) {
        if (isset($list)) {
            $list .= ", $item";
        } else {
            $list = $item;
        }
    }
    if (isset($list)) {
        return $list;
    } else return '';
}

然后你可以这样称呼它:

$unitnum = implode('/',array_filter(array($unit,$num)));
if ($unitnum || $street) {
    $streetaddress = trim("$unitnum $street");
} else $streetaddress = '';
if ($level) {
    $level = "L$level";
}
echo makeList($level, $streetaddress, $suburb, $state $postcode, $country).'.';
于 2009-04-15T14:03:40.937 回答
1

好的,拿那个!(但不要太严重^^)

<?php

function bothOrSingle($left, $infix, $right) {
    return $left && $right ? $left . $infix . $right : ($left ? $left : ($right ? $right : null));
}

function leftOrNull($left, $postfix) {
    return $left ? $left . $postfix : null;
}

function rightOrNull($prefix, $right) {
    return $right ? $prefix . $right : null; 
}

function joinargs() {
    $args = func_get_args();
    foreach ($args as $key => $arg) 
        if (!trim($arg)) 
            unset($args[$key]);

    $sep = array_shift($args);
    return join($sep, $args);
}

$level    = 2;
$unit     = 1;
$num      = 123;
$street   = 'Cool St';
$suburb   = 'Funky Town';
$state    = 'ABC';
$postcode = 2000;
$country  = 'Australia';

echo "\n" . '"' . joinargs(', ', rightOrNull('L', $level), bothOrSingle(bothOrSingle($unit, '/', $num), ' ', $street), bothOrSingle($state, ' ', $postcode), bothOrSingle($country, '', '.')) . '"';

// -> "L2, 1/123 Cool St, ABC 2000, Australia."

$level    = '';
$unit     = '';
$num      = '';
$street   = 'Cool St';
$suburb   = '';
$state    = 'ABC';
$postcode = '';
$country  = '';

echo "\n" . '"' . joinargs(
    ', ', 
    leftOrNull(
        joinargs(', ', 
            rightOrNull('L', $level), 
            bothOrSingle(bothOrSingle($unit, '/', $num), ' ', $street), 
            bothOrSingle($state, ' ', $postcode), 
            $country
        ),
        '.'
    )
) . '"';

// -> "Cool St, ABC."


$level    = '';
$unit     = '';
$num      = '';
$street   = '';
$suburb   = '';
$state    = '';
$postcode = '';
$country  = '';

echo "\n" . '"' . joinargs(
    ', ', 
    leftOrNull(
        joinargs(', ', 
            rightOrNull('L', $level), 
            bothOrSingle(bothOrSingle($unit, '/', $num), ' ', $street), 
            bothOrSingle($state, ' ', $postcode), 
            $country
        ),
        '.'
    )
) . '"';

// -> "" (even without the dot!)

?>

是的,我知道 - 看起来有点像brainfuck。

于 2009-04-15T17:03:22.673 回答
0

我总是发现使用语言的数组方法既快速又容易。例如,在 PHP 中:

<?php
echo join(',', array('L'.$level, $unit.'/'.$num, 
          $street, $suburb, $state, $postcode, $country));
于 2009-04-15T13:52:19.323 回答
0
<?php
    $level  = 'foo';
    $street = 'bar';
    $num    = 'num';
    $unit   = '';

    // #1: unreadable and unelegant, with arrays
    $values   = array();
    $values[] = $level ? 'L' . $level : null;
    // not very readable ...
    $values[] = $unit && $num ? $unit . '/' . $num : ($unit ? $unit : ($num ? $num : null));
    $values[] = $street ? $street : null;

    echo join(',',  $values);


    // #2: or, even more unreadable and unelegant, with string concenation
    echo trim( 
        ($level ? 'L' . $level . ', ' : '') . 
        ($unit && $num ? $unit . '/' . $num . ', ' : ($unit ? $unit . ', ' : ($num ? $num . ', ': '')) .
        ($street ? $street . ', ': '')), ' ,');

    // #3: hey, i didn't even know that worked (roughly the same as #1):
    echo join(', ', array(
        $level ? 'L' . $level : null,
        $unit && $num ? $unit . '/' . $num : ($unit ? $unit : ($num ? $num : null)),
        $street ? $street : null
    ));
?>
于 2009-04-15T15:03:45.317 回答
0

只需取出最后一个逗号,即用空替换它。

$string1 = "L$level, $unit/$num $street, $suburb, $state $postcode, $country.";
$string1 = eregi_replace(", \.$", "\.", $string1);
echo $string1;

这将完成工作。

于 2009-04-15T15:34:06.600 回答