2009-04-15 66 views
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; 
} 

回答

0

我總是發現它的速度更快和更容易使用的語言的陣列方法。例如,在PHP:

<?php 
echo join(',', array('L'.$level, $unit.'/'.$num, 
      $street, $suburb, $state, $postcode, $country)); 
+0

不會解決問題。 – Tobias 2009-04-15 13:57:42

+0

像我一樣(見下文,#3)。不幸的是,這使得它不那麼優雅。 – stefs 2009-04-15 16:31:35

1

雖然菲利普的回答解決你的問題,我希望通過Eric Lippert有以下博客文章來補充它。雖然他的討論是在C#中,但它適用於任何編程語言。

1

有一個簡單的解決方案,你的第二個問題:

for($i=0; $i<=5; $i++) 
    $o .= "$i,"; 
echo chop($o, ','); 
1

菲利普的解決方案可能是最好的使用數組時(如果你沒有過濾掉空值),但如果你不能使用該陣列的功能 - 例如,與查詢結果打交道時從mysqli_fetch_object() --then一個解決方案返回僅僅是一個簡單的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).'.'; 
+0

我認爲這是越來越近,街道地址也可能需要使用makeList功能,因爲它仍然會返回的空間和/或者如果這三個變量是空白......因此,問題的主要部分... – 2009-04-15 15:52:46

+0

你也對數組提出了一個很好的觀點,更常見的是數據來自MySQL,這意味着需要額外的一步來創建一個數組或多個數組。 – 2009-04-15 15:56:05

+0

有時,像街道地址和關卡這樣的項目,最直接的解決方案就是使用簡單的if語句來進行自定義格式設置。構建自定義函數來處理一次性格式問題是不切實際的。 – Calvin 2009-04-15 16:08:47

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並加入呼叫到一個單獨的方法,並使用:

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調用刪除空條目,否則delimeters仍然會打印出來。

對於你的第二個例子,添加項目到一個數組,然後使用連接到插入分隔符:

$arr = array(); 
for($i=0; $i=<5; $i++) 
{ 
    $arr[] = $i; 
} 
echo(join(',', $arr)); 
+0

如果我不得不維護你的代碼,我寧願在這個問題上看到類似「艱苦」的方法。這種單線解決方案是醜陋的。 – 2009-04-15 15:21:40

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 
    )); 
?> 
0

就掏出最後一個逗號,即用什麼替代它。

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

這會做這項工作。

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!) 

?> 

是的,我知道 - 看起來有點像腦袋。除非你添加的每個元素之前檢查isset或空