2009-07-21 47 views
10

假設您正在製作博客軟件,並且想要顯示條目所獲得的評論數量。你可能會做這種方式:最優雅的方式來處理單打/複數?

[Entry title] 
[Content........] 
[ <?php print($numComments;) ?> Comments] 

可能導致其中:

[Entry title] 
[Content........] 
5 Comments 

但是,如果一個條目只有1條評論,我想在網上說的,而不是「評論」「評論」。在線if/else是醜陋的和重複的。

處理這個問題的最佳方法是什麼?

+4

+1對於您的用戶名,因爲它告訴我。這很聰明,我很想知道你爲此單獨獲得了多少點讚賞。 :) – Dusty 2009-07-21 20:19:02

+1

我一半試圖downvote只是爲了抵消upvote的人的影響 – 2009-07-21 22:59:44

回答

13

請使用ngettext功能這樣的事情。它 允許您正確處理英語和其他 語言的複數,一勞永逸。您可以使用這樣的:

printf(ngettext("%d Comment", "%d Comments", $numComments), $numComments); 

ngettext函數將返回第一個格式化字符串("%d Comment")如果有隻是一個單一的評論和第二格式 串("%d Comments")如果有更多。 printf函數將 然後將該數字放入字符串中。

這似乎是一個大量的工作,但它是非常強大:它的工作原理與 有不止一個複數形式語言 - 他們 實際存在(!)。 PHP手冊給出了一個「窗口」 這個詞,它變成了「1 okno」,「2 okna」和「5 oken」在一些異國情調的 語言中我不認識...

如果你是隨之而來的關於使用ngettext,那麼你的未來用戶 從遙遠的國家會很感激你:-)

編輯:正如評論所說,有一個單一的功能到 做上面:

function pluralize($num, $singleWord, $pluralWord) { 
    return printf(ngettext($singleWord, $pluralWord, $num), $num); 
} 

默認情況下,xgettext不會承認這個新功能,但你可以 與--keyword標誌添加它。給定一個文件test.php

echo ngettext("foo", "foos", 1); 
echo pluralize(2, "bar", "bars"); 

你可以用

xgettext --keyword=pluralize:2,3 test.php 

產生的messages.po文件中提取字符串有條目這樣的:

#: test.php:7 
msgid "foo" 
msgid_plural "foos" 
msgstr[0] "" 
msgstr[1] "" 

#: test.php:8 
msgid "bar" 
msgid_plural "bars" 
msgstr[0] "" 
msgstr[1] "" 

譯者將在每個複數形式填寫與正確的 在消息目錄標題中形成了「Plural-Forms」行,您將成爲 支持所有語言。

3

創建一個函數,該函數需要一個數字和一個單詞,並返回一個包含兩者的字符串。當數字大於1時,它會附加一個「s」(或諮詢您建立的字典)。

+1

我會使功能添加s如果數字不是1,所以0也獲得複數形式。 – 2009-07-21 19:58:58

+0

你會怎麼稱呼這樣的功能? – 2009-07-21 20:01:48

+0

複數似乎是最合適的名稱。 – Brandon 2009-07-21 20:03:02

2

不是最優雅的,但最容易輸出「Comment(s)」。

[Entry title] 
[Content........] 
1 Comment(s) 
4

爲什麼不採取更人性化的東西的時候....

switch ($numComments) 
{ 
    case 0: 
     echo "Be the first to write a comment"; 
     break; 
    case 1: 
     echo "Just one comment so far"; 
     break; 
    default: 
     echo "There are $numComments comments"; 

} 
3

我很驚訝,沒有人認爲還沒有,但我通常做的是使用條件運算符:

string commentWord = numComments != 1 ? "Comments" : "Comment"; 

注意:字符串當然不應該像這樣硬編碼,而是從某個資源存儲庫加載,在那裏存儲的格式化佔位符爲該數字,以便您可以處理其中數字應該會出現最後一個(或中間)語言:

// should load "{0} Comments" or "{0} Comment" if we run in an English locale 
string comments = string.Format(
     numComments != 1 ? GetResource("Comments") : GetResource("Comment"), 
     numComments); 
2

在C/C++中,您可以執行以下操作。你可能可以在PHP中做類似的事情。

printf("%d %s\n", numComments, numComments == 1 ? "Comment" : "Comments"); 

下也可以,但是你可以用\b(退格鍵)遇到問題正在不同的實現方式不正確處理。

printf("%d Comment%s\n", numComments, numComments == 1 ? " \b" : "s"); 

使用\0(空字符)打印什麼,而是印在我的執行空間。