名词复数化的模块化方法


Modular approach for pluralizing nouns

我想我们之前都遇到过这样的问题,即应用程序说"还剩1分钟"或类似的内容。我认为这个观察结果证明了许多程序员忽略了这个问题。

在我的项目中,我通常会做这样的事情来解释名词的复数化:

$Count = count($Items);
$Noun = 'minute';
if ($Count != 1)
{
    $Noun .= 's';
}
echo sprintf('There are %u %s remaining.', $Count, $Noun);

我对这种方法有几个问题:

  1. 它让程序员在每次需要生成字符串时都要做这个复数检查,所以代码永远不能被重用。
  2. 它不必要地增加了应用程序代码,并抑制了可读性。
  3. 它不是通用的。这个例子之所以有效,是因为minutes是minute的复数形式。"羊"、"牛"或"真菌"呢?
谁有什么通用的、模块化的方法来解决这个问题?我可以接受不止一个答案。

实现一个接受数字和所有单数和复数形容词的函数是很常见的。

所以示例调用可以是

echo 'There are ' $count . ' ' . pluralize($count, array('minute', 'minutes')) . ' remaining';

如果您决定将您的应用程序翻译成多种语言,此链接将帮助您正确地使用复数形式:http://translate.sourceforge.net/wiki/l10n/pluralforms

ps:我提出的建议将适用于任何语言,如果你传递额外的第三个参数language,它将指定使用哪个复数公式。

我认为使用一般方法会过分强调性能,而忽略了这段小代码的有用性。为了实现通用的方法,你应该使用字典或类似的东西,这与好处相比是不必要的。也许像这样更简单的一行是性能和实用性之间的正确权衡。

$Count = count($Items);
$Noun = 'minute';
echo sprintf('There are %u %s(s) remaining.', $Count, $Noun);

处理这个问题的一个简单方法是创建一个接受三个参数的函数:数字、单词的单数拼写和单词的复数拼写。该函数根据值返回单词的单数或复数形式。它仍然把责任推给程序员,但它比这里显示的更清晰。