มีอัลกอริทึมใดใน c # ที่จะทำให้เป็นเอกพจน์ - พหูพจน์ได้หรือไม่?


106

มีอัลกอริทึมใดใน c # ที่จะทำให้เป็นเอกพจน์ - พหูพจน์ (ในภาษาอังกฤษ) หรือมีไลบรารี. net เพื่อทำสิ่งนี้ (อาจเป็นภาษาอื่นด้วย)

คำตอบ:


182

นอกจากนี้คุณยังมีSystem.Data.Entity.Design.PluralizationServices.PluralizationService

UPDATE : คำตอบเก่าสมควรได้รับการปรับปรุง ตอนนี้ยังมี Humanizer: https://github.com/MehdiK/Humanizer


2
อืมคุณอนุญาตให้แจกจ่ายซ้ำหรือใช้ Design DLL? ฉันถามอย่างนั้นเพราะฉันรู้ว่าใบอนุญาตสำหรับ DevExpress ห้ามไม่ให้แจกจ่าย. ออกแบบ DLL ใด ๆ
Pierre-Alain Vigeant

58
การเปิดโค้ดด้วย ILSpy จะแสดงคลาสที่เรียกว่า EnglishPluralizationService ซึ่งมีกรณีพิเศษมากมายที่กำหนดไว้และทำให้การอ่านน่าสนใจ ฉันชอบ 'pneumonoultramicroscopicsilicovolcanoconiosis' เป็นพิเศษซึ่งฉันพบว่าตัวเองใช้ตลอดเวลาในรูปแบบเอนทิตีของฉัน ... 8o)
MrKWatkins

7
ฉันเดาได้ว่ามีการเพิ่มเข้ามาอย่างไร ผู้ทดสอบยื่นข้อบกพร่องใน dev โดยแจ้งว่าใช้ไม่ได้กับคำดังกล่าว Dev แก้ไขแล้ว ทั้งสองแบ่งปันเสียงหัวเราะ
merlinbeard

2
@MrKWatkins ฟังดูเหมือน 'supercalifragilisticexpialidocious'
Corstian Boerman

1
Humanizer เป็นคำแนะนำที่ดี แน่นอนว่าฉันได้ติดตั้ง 15% ด้วยตัวเองก่อนที่จะพบว่ามีอยู่จริง
Casey

18

ฉันสามารถทำเพื่อเอสเปรันโตได้โดยไม่มีกรณีพิเศษ!

string plural(string noun) { return noun + "j"; }

สำหรับภาษาอังกฤษก็จะเป็นประโยชน์ในการทำความคุ้นเคยกับกฎระเบียบสำหรับการพหูพจน์ปกติของคำนามเช่นเดียวกับการที่ผิดปกติพหูพจน์ของคำนาม มีบทความ Wikipedia ทั้งหมดเกี่ยวกับพหูพจน์ภาษาอังกฤษซึ่งอาจมีข้อมูลที่เป็นประโยชน์เช่นกัน


5
คุณควรโยนถ้าคุณส่งคำกริยาหรือคำวิเศษณ์!
Timwi

1
@ แมท: แน่นอนว่านี่เหมาะสมสำหรับกรณีเสนอชื่อ; ฉันเชื่อว่าการขยายวิธีการนี้ไปสู่คดีที่กล่าวหานั้นตรงไปตรงมาสำหรับผู้อ่านที่ชาญฉลาด
Greg Hewgill

14

ORM ส่วนใหญ่มีการแทงแม้ว่าโดยทั่วไปจะไม่สมบูรณ์แบบ ฉันรู้ว่า Castle มีInflector Class ที่คุณอาจจะโผล่ไปรอบ ๆ การทำอย่าง "สมบูรณ์แบบ" ไม่ใช่เรื่องง่าย ("กฎ" ภาษาอังกฤษไม่ใช่กฎจริงๆ :)) ดังนั้นจึงขึ้นอยู่กับว่าคุณพอใจกับวิธีการ "เดาที่สมเหตุสมผล" หรือไม่


จากคำแนะนำของคุณฉันค้นหา "Inflector" และพบandrewpeters.net/inflectornetซึ่งโดยพื้นฐานแล้วน่าจะเหมือนกับ Castle one
Ronnie

4
จริงๆแล้วมันไม่เหมือนกันโดยพื้นฐานแล้วมันเหมือนกัน
David Pfeffer

12

ฉันโกงใน Java - ฉันต้องการสร้างสตริงที่ถูกต้องสำหรับ "There were n something (s)" ดังนั้นฉันจึงเขียน foll วิธียูทิลิตี้ที่โอเวอร์โหลดเล็กน้อย:

static public String pluralize(int val, String sng) {
    return pluralize(val,sng,(sng+"s"));
    }

static public String pluralize(int val, String sng, String plu) {
    return (val+" "+(val==1 ? sng : plu)); 
    }

เรียกเช่นนั้น

System.out.println("There were "+pluralize(count,"something"));
System.out.println("You have broken "+pluralize(count,"knife","knives"));

สิ่งนี้ครอบคลุมเฉพาะส่วนเล็ก ๆ ของไวยากรณ์แม้ว่าจะไม่ได้คำนึงถึงคำต่างๆเช่นแบบทดสอบปาร์ตี้แบ่งครึ่งหนูดัชนี ฯลฯ เป็นการแทงครั้งแรกที่ดี แต่มีกฎอื่น ๆ อีกมากมายที่ควรประมวลผลก่อน .
Jeremy S

4
@ Jeremy: ทำไมไม่: println ("คุณผ่านแล้ว" + singularPlural (count, "quiz", "quizzes") + "so far")
Lawrence Dol

ฉันอาจตีความคำถามแตกต่างออกไป ฉันคิดว่าอัลกอริทึมควรกำหนดรูปพหูพจน์โดยไม่มีคำแนะนำใด ๆ จากนักพัฒนาในขณะที่วิธีการของคุณให้ความสำคัญกับการรู้ว่ารูปพหูพจน์เป็นอย่างไรสำหรับนักพัฒนา
Jeremy S

3
@ เจเรมี: ดังนั้น "ฉันโกง ... " นำเข้า - ดูเหมือนจะไม่รับประกันการลดลง
Lawrence Dol

1
เห็นด้วย ฉันยังคิดว่าข้อมูลที่ให้มานั้นมีประโยชน์ซึ่งเป็นเหตุผลว่าทำไมการโหวตไม่มาจากฉัน ฉันไม่ได้ลงคะแนนโดยทั่วไปตามแนว "ขยะของผู้ชายคนหนึ่ง ... "
Jeremy S

10

ฉันได้สร้างไลบรารีเล็ก ๆ สำหรับสิ่งนี้ใน. net (C #) เรียกว่า Pluralizer (ไม่แปลกใจเลย)

มันหมายถึงการทำงานกับประโยคเต็มบางอย่างเช่น String.Format ทำ

โดยทั่วไปจะใช้งานได้ดังนี้:

var target = new Pluralizer();
var str = "There {is} {_} {person}.";

var single = target.Pluralize(str, 1);
Assert.AreEqual("There is 1 person.", single);

// Or use the singleton if you're feeling dirty:
var several = Pluralizer.Instance.Pluralize(str, 47);
Assert.AreEqual("There are 47 people.", several);

นอกจากนี้ยังสามารถทำได้มากกว่านั้น อ่านข้อมูลเพิ่มเติมเกี่ยวกับเรื่องนี้ในบล็อกของฉัน นอกจากนี้ยังมีใน NuGet


ข้อได้เปรียบเหนือSystem.Data.Entity.Design.PluralizationServices.PluralizationService ?
John Saunders

4
ใช่ไลบรารีนั้นทำเพียงคำเดียวและคำนามเท่านั้น (แม้ว่า Pluralizer จะใช้คลาสนั้นเป็นการภายใน) ไลบรารีนี้ช่วยให้เขียนทั้งประโยคได้ง่ายขึ้น ดูบล็อกของฉันสำหรับตัวอย่างเพิ่มเติม Pluralizer.Instance.Pluralize ("{She} {is} จะไป {เธอ | ของพวกเขา} {home}.", 5)
Jay Querido

Shaun Wilson - คอมพิวเตอร์ของฉันอยู่ในส่วนต่างๆ ฉันกำลังเร่งดำเนินการสำรองข้อมูลและจะอัปเดตภายในหนึ่งหรือสองวัน ในเวลานั้นnuget.org/packages?q=pluralizer
Jay Querido

8

ฉันตีหนึ่งเข้าด้วยกันตามพหูพจน์ของ Rails คุณสามารถดูโพสต์บล็อกของฉันได้ที่นี่หรือบน github ที่นี่

output = Formatting.Pluralization(100, "sausage"); 

3
ขอบคุณสำหรับการแบ่งปัน. ดีใจที่ไม่ต้องอ้างอิงชุดประกอบอื่น
hofnarwillie

1
เรียบง่ายและสวยงาม! แต่พลาดฟังก์ชันSingularize
amd

5

ตามที่เป็นคำถามสำหรับ C # นี่คือรูปแบบที่ดีในการแก้ปัญหาของ Software Monkey (อีกครั้งคือ "โกง" แต่สำหรับฉันแล้ววิธีที่ใช้งานได้จริงและนำกลับมาใช้ใหม่ได้มากที่สุด):

    public static string Pluralize(this string singularForm, int howMany)
    {
        return singularForm.Pluralize(howMany, singularForm + "s");
    }

    public static string Pluralize(this string singularForm, int howMany, string pluralForm)
    {
        return howMany == 1 ? singularForm : pluralForm;
    }

การใช้งานมีดังนี้:

"Item".Pluralize(1) = "Item"
"Item".Pluralize(2) = "Items"

"Person".Pluralize(1, "People") = "Person"
"Person".Pluralize(2, "People") = "People"

3

Subsonic 3 มีInflectorคลาสที่ทำให้ฉันประทับใจเมื่อเปลี่ยนPersonเป็นPeople. ฉันมองไปที่แหล่งที่มาและพบว่ามันโกงเล็กน้อยตามธรรมชาติด้วยรายการที่เข้ารหัส แต่นั่นเป็นวิธีเดียวที่จะทำในภาษาอังกฤษและวิธีที่มนุษย์ทำ - เราจำเอกพจน์และพหูพจน์ของแต่ละคำได้และไม่เพียงแค่ใช้กฎ . เนื่องจากไม่มีผู้ชาย / ผู้หญิง (/ เป็นกลาง) ที่จะเพิ่มลงในส่วนผสมจึงง่ายกว่ามาก

นี่คือตัวอย่าง:

AddSingularRule("^(ox)en", "$1");
AddSingularRule("(vert|ind)ices$", "$1ex");
AddSingularRule("(matr)ices$", "$1ix");
AddSingularRule("(quiz)zes$", "$1");

AddIrregularRule("person", "people");
AddIrregularRule("man", "men");
AddIrregularRule("child", "children");
AddIrregularRule("sex", "sexes");
AddIrregularRule("tax", "taxes");
AddIrregularRule("move", "moves");

AddUnknownCountRule("equipment");

มันอธิบายถึงคำบางคำที่ไม่มีความเทียบเท่าพหูพจน์เช่นตัวอย่างอุปกรณ์ อย่างที่คุณสามารถบอกได้ว่ามันRegexแทนที่ง่ายๆโดยใช้ $ 1

อัปเดต:
ดูเหมือนว่า Subsonic Inflectorจะใส่ชื่อคลาสCastle ActiveRecordInflector !


2

เอกสารประกอบจาก MSDN ไม่มากนักเกี่ยวกับการใช้งานเฉพาะของคลาส PluralizationService ดังนั้นนี่คือคลาสทดสอบหน่วย (NUnit) เพื่อแสดงการใช้งานพื้นฐาน สังเกตกรณีทดสอบแปลก ๆ ที่ด้านล่างซึ่งแสดงว่าบริการไม่สมบูรณ์แบบเมื่อเป็นรูปพหูพจน์ที่ไม่ได้มาตรฐาน

[TestFixture]
public class PluralizationServiceTests
{
    [Test]
    public void Test01()
    {
        var service = PluralizationService.CreateService(CultureInfo.CurrentCulture);

        Assert.AreEqual("tigers", service.Pluralize("tiger"));
        Assert.AreEqual("processes", service.Pluralize("process"));
        Assert.AreEqual("fungi", service.Pluralize("fungus"));

        Assert.AreNotEqual("syllabi", service.Pluralize("syllabus")); // wrong pluralization
    }
}


1

การใช้ฐานข้อมูลตัวอย่าง Northwind ของ Microsoft:

 System.Data.Entity.Design.PluralizationServices.PluralizationService.CreateService(new System.Globalization.CultureInfo("en-US"));

Singularize ไม่เป็น Singularize "Order_Details" แต่จะส่งกลับ "Order_Details" พร้อมกับsต่อท้าย งานรอบล่ะ?


1
นี่คือคำถามไม่ใช่คำตอบสำหรับคำถาม ... แต่เป็น Pluralize () และ Singularize () ใช้ได้กับคำในพจนานุกรมเท่านั้น มีวิธีเพิ่มคำโดยใช้ ICustomPluralizationMapping.AddWord แต่อย่างน้อยสำหรับฉันนั่นก็ไม่ใช่วิธีแก้ปัญหาที่ดีนักเมื่อคุณอาจมีคำที่ไม่เป็นจริงมากมายเช่นชื่อรหัส
tordal

@tordal ขอบคุณนี่คือสิ่งที่ฉันมาถามคำถามนี้
ชาด
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.