基于某些集合大小处理单数/复数单词的有效方法[关闭]
Posted
技术标签:
【中文标题】基于某些集合大小处理单数/复数单词的有效方法[关闭]【英文标题】:Effective way to handle singular/plural word based on some collection size [closed] 【发布时间】:2011-03-12 11:48:31 【问题描述】:在我的工作项目中有很多实例,我需要在一个句子中显示某个集合的大小。例如,如果集合的大小为 5,它将显示“5 个用户”。如果它的大小为 1 或 0,它会说“1 个用户”或“0 个用户”。现在,我正在使用 if-else 语句来确定是否打印“s”,这很乏味。
我想知道是否有一个开源 JSP 自定义标签库可以让我完成这项工作。我知道我可以自己写一个……基本上,它将有 2 个这样的参数:<lib:display word="user" collection="userList" />
。根据集合大小,它将确定是否附加“s”。但是,这个实现不会太健壮,因为我还需要处理“ies”,而有些词不使用其中的任何一个。因此,与其创建一个半生不熟的工具,我希望有一个更强大的库我可以立即使用。在这种情况下,我不太担心在单词前面加上 is/are。
顺便说一句,我使用 Java。
非常感谢。
【问题讨论】:
相关***.com/questions/5907296/… 【参考方案1】:看看inflector,这是一个java项目,它可以让你做Noun.pluralOf("user")
或Noun.pluralOf("user", userList.size())
,它可以处理一堆变化和不寻常的情况(person->people、loaf->loaves等。 ),以及让您在必要时定义自定义映射规则。
【讨论】:
可用于 Java 的丰富内容令人惊叹!感谢您提供此信息,这可以使我和其他人免于进入 RoR 的内部。 +1。下一个:KitchenSink.jar :) 好吧……说真的,哇! :) 我以为你只是在拉我的腿,事实上,这是真的!非常感谢,我确实很快就会搞砸了。 @Carl:是的,我们也需要 kitchenSink.jar。 如果你和我一样无法访问 java.net 上的 Inflector 项目,可以从这里获取:mirrors.ibiblio.org/pub/mirrors/maven2/net/java/dev/inflector/… 我还在 github 上看到了一个变形器。不知道是不是同一个...github.com/flextao/inflector 来自他们的文档:“对于来自维基词典的整套 163518 个单词,Evo Inflector 为其中 68.4% 的单词返回正确答案”。因此在使用它之前我会非常小心?【参考方案2】:嗯,我不太明白你为什么需要一个库。我认为这样做的功能是微不足道的:
public String singlePlural(int count, String singular, String plural)
return count==1 ? singular : plural;
调用看起来像:
singlePlural(count, "user", "users");
singlePlural(count, "baby", "babies");
singlePlural(count, "person", "people");
singlePlural(count, "cherub", "cherubim");
... etc ...
也许这个库做了一大堆其他使它有用的事情。我想你可以说它提供了所有复数形式的字典,但是在任何给定的程序中,你不关心语言中所有单词的复数,只关心你在这个程序中使用的那些。我想如果在编译时不知道可能是单数或复数的单词,如果它是用户输入的东西,那么我想要一本第三方字典而不是尝试自己构建一个。
编辑
我突然想到,您正在寻找的是一个通用复数的函数,它体现了一组规则,例如“通常只添加 's',但如果单词以 'y' 结尾,则更改 'y'到'ies',如果它以's'结尾,则将其更改为'ses',......”等。我认为用英语这对于任何实际目的都是不可能的:有太多特殊情况,比如“人/人” " 和 "child/children" 等。我认为你能做的最好的事情就是有一个通用的 "add an 's'" 规则,也许还有其他一些常见的情况,然后是一长串例外情况。也许在其他语言中,人们可以想出一个相当简单的规则。
正如我所说,如果这个词在编译时是未知的,而是来自一些用户输入,那么是的,第三方词典是非常可取的。
【讨论】:
我会记住这种方法,但就我而言,名词是以编程方式从数据库中提取的。 啊,好吧,这会让你看到我提到的“如果在编译时不知道这个词”异常。所以是的,在这种情况下,拥有第三方词典非常有用。查看我的更新。 您的方法无法处理多种语言。复数和单数的变化可能是一团糟。您可以这样做的一种方法是:返回字符串[复数];不验证代码,但你应该明白。 Rule 是一个函数,用于确定复数索引。如果复数不存在,应该有一个返回索引 0 的测试。反正这个方法很烂。您应该只需要插入“键”和计数......就像在 gettext 中一样。 @Sybiam:当你说它不起作用时,你的意思是我的第一种方法,即只说“这里是单数,这里是复数”?还是我提到规则的第二种方法?我的意图是说那是个坏主意。这在英语中是非常不切实际的,因为有很多例外。在拉丁语中这会很困难,因为有五个基本规则,然后是许多例外。我想它会在世界语中起作用。任何其他具有形成复数形式的一致规则的语言?我的猜测是很少。 @Sybiam:我的意思是说,我认为我的第一种方法几乎适用于任何语言。在此问题其他地方所述的具有单/双/复数的语言中,您需要三种形式。如果还有其他语言变得更复杂,那么我想它会崩溃。 I18n'ing 增加了另一个层次的复杂性。【参考方案3】:这在英语以外的其他语言中变得复杂,该变形器旨在在未来支持。
我熟悉捷克语,其中 user = uživatel 和:
1 uživatel
2 uživatelé
3 uživatelé
4 uživatelé
5 uživatelů
...
您可以看到为什么用硬编码的单数+复数编写的程序会变得不支持 i18n。
编辑: Java11 允许您使用以下内容:
ChoiceFormat fmt = new ChoiceFormat("1#uživatel | 1.0< uživatelé | 4< uživatelů");
System.out.println(fmt.format(1));
System.out.println(fmt.format(4));
System.out.println(fmt.format(5));
ChoiceFormat documentation
【讨论】:
这就是为什么我喜欢不关心单数或复数的语言,例如马来语,例如:“1 orang”、“2 orang”,无论 x 用户如何。 :) 真的吗?你是说在捷克有一个表格 1,另一个表格 2-4,还有一个不同的表格 5?很有意思。为什么是 5 而不是 6 或 42?不同的词有不同的数字吗?我不是语言学家,但这听起来很奇怪,很有趣。 真的。不仅仅是捷克。您可能有兴趣在此处阅读“双”作为“单数”和“复数”的补充:en.wikipedia.org/wiki/Dual_(grammatical_number) @Jay 我不懂捷克语,但其他语言对单词有性别(有点像你有英语的演员/女演员,只对所有单词)和两种性别的单数/复数形式。此外,在罗马尼亚语中,根据名词在句子中的作用,后缀会有所不同。虽然您在英语中可能会说“对用户”,但我们会在我们的用户词中添加后缀“-ului”(utilizator -> utilizatorului;这是针对男性版本的)。这使得这些语言不那么模棱两可,但也更难学习。 (动词也有基于人/时间组合的后缀)。 啊,我们还使用后缀制作铰接形式,因此“用户”也有不同的形式(utilizator -> utilizatorul)【参考方案4】:此功能内置在 Ruby on Rails 中。我不知道具体在哪里,但是在源代码中应该很容易找到,然后你可以简单地抄写代码。
编辑:找到了一些代码:
inflector.rb(非常有帮助的 cmets!) inflections.rb(广泛的词表)如果我没记错的话,这主要是在大多数单词上附加一个“s”,尽管我相信有一些常见例外的列表(可能是散列,错误字典)。值得注意的是从“人”到“人”的转换:)
如果您决定要将其国际化为英语以外的其他语言,您当然会陷入痛苦的世界。欢迎来到高度不规则语法的世界,祝你好运!
【讨论】:
谢谢!地狱,如果我必须将其国际化,我还不如编造自己的语言,其中复数词总是以 YAY 结尾...例如:5 userYAY。 :)以上是关于基于某些集合大小处理单数/复数单词的有效方法[关闭]的主要内容,如果未能解决你的问题,请参考以下文章
在 Ruby on Rails 中测试一个单词是单数还是复数