2009-07-21 125 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(空字符)打印什么,而是印在我的执行空间。

相关问题