उपयोगकर्ता संदेशों में बहुलता


106

कई बार, जब उपयोगकर्ता को दिखाने के लिए संदेश जनरेट करते हैं, तो संदेश में कई ऐसी चीजें होंगी, जिनके बारे में मैं ग्राहक को सूचित करना चाहता हूं।

मैं एक उदाहरण दूंगा: ग्राहक ने 1 और ऊपर से कई मदों का चयन किया है, और हटाए जाने पर क्लिक किया है। अब मैं ग्राहक को एक पुष्टिकरण संदेश देना चाहता हूं, और मैं उन मदों की संख्या का उल्लेख करना चाहता हूं, जिन्हें उसने चुना है कि वह वस्तुओं के एक समूह का चयन करके गलती करने की संभावना को कम कर दे और जब वह केवल एक को हटाना चाहता है तो उसे हटा दें उन्हें।

एक तरीका यह है कि जेनेरिक संदेश को इस तरह बनाया जाए:

int noofitemsselected = SomeFunction();
string message = "You have selected " + noofitemsselected + " item(s). Are you sure you want to delete it/them?";

"समस्या" यहाँ इस मामले में जहां है noofitemselected1 है, और हम लिखने के लिए है आइटम और यह बजाय आइटम और उन्हें

मेरा सामान्य समाधान कुछ इस तरह होगा

int noofitemsselected = SomeFunction();
string message = "You have selected " + noofitemsselected + " " + (noofitemsselected==1?"item" : "items") + ". Are you sure you want to delete " + (noofitemsselected==1?"it" : "them") + "?";

यह वास्तव में तेजी से काफी लंबा और काफी बुरा हो जाता है यदि कोड के अंदर संख्या बहुलता के कई संदर्भ हैं, और वास्तविक संदेश को पढ़ना मुश्किल हो जाता है।

तो मेरे सवाल बस है। क्या इस तरह संदेश भेजने के कोई बेहतर तरीके हैं?

संपादित करें

मुझे लगता है कि बहुत से लोग इस मामले में बहुत त्रस्त हो गए हैं, जिनका मैंने उल्लेख किया है कि संदेश को एक संदेश बॉक्स के अंदर प्रदर्शित किया जाना चाहिए, और बस एक उत्तर दिया है कि संदेश बॉक्स का उपयोग करने से कैसे बचें, और यह सब अच्छा है ।

लेकिन याद रखें कि बहुवचन की समस्या संदेश बॉक्स के अतिरिक्त कार्यक्रम के अन्य स्थानों पर भी लागू होती है। उदाहरण के लिए, ग्रिड में चयनित लाइनों की संख्या प्रदर्शित करने वाली ग्रिड के साथ एक लेबल में बहुवचन के बारे में एक ही समस्या होगी।

तो यह मूल रूप से अधिकांश पाठों पर लागू होता है जो प्रोग्रामों से किसी तरह से आउटपुट किया जाता है, और फिर समाधान इतना सरल नहीं है कि प्रोग्राम को केवल टेक्स्ट में आउटपुट न करने के लिए बदल दें :)


6
@ 0xA3: मैं वास्तव में नहीं जानता कि क्या हर भाषा का बहुवचन है जो आसानी से "आइटम" के रूप में व्यक्त किया जाता है।
जेन्स

5
आपको शायद स्थानीयकरण के बारे में भी सोचना चाहिए। यह समस्या पूरी तरह से बदतर हो सकती है।
एलेक्स ब्राउन

4
@ जेन्स: वे आम तौर पर, कम से कम सुविधाजनक तरीके से संभव नहीं होते हैं। 5-अनन्तता की तुलना में कुछ भाषाओं में 2-4 के लिए अलग-अलग बहुवचन हैं, यह सब लिंग के आधार पर है। "प्राकृतिक भाषाएँ: स्थानीयकरण पागलपन! आपके पास एक कंप्यूटर के लिए जल्द ही आ रहा है!"
पिस्कोर ने

29
IMO, कुछ भी नहीं बनाता है प्रोग्रामर उपयोगकर्ताओं को बुरी बहुलता की तुलना में आलसी दिखते हैं।
ग्रेग

4
@ Øyvind: +1 आपके संपादन के लिए। ऐसा लगता है कि कई "उत्तरदाता" यहां यह साबित करने पर अधिक मंशा रखते हैं कि आपका प्रश्न गलत है, बजाय इसके कि कोई समाधान प्रस्तुत किया जाए। विरोधी समाधान, यदि आप करेंगे।
mwolfe02

जवाबों:


53

अगर कभी कोई मौका है, चाहे कितना छोटा हो, कि इस एप्लिकेशन को अन्य भाषाओं में अनुवाद करने की आवश्यकता होगी तो दोनों गलत हैं। ऐसा करने का सही तरीका है:

string message = ( noofitemsselected==1 ?
  "You have selected " + noofitemsselected + " item. Are you sure you want to delete it?":
  "You have selected " + noofitemsselected + " items. Are you sure you want to delete them?"
);

ऐसा इसलिए है क्योंकि विभिन्न भाषाएं बहुलता को अलग-अलग तरीके से संभालती हैं। मलय जैसे कुछ लोगों के पास वाक्य-विन्यास भी नहीं है, इसलिए तार आम तौर पर समान होते हैं। दो तारों को अलग करने से बाद में अन्य भाषाओं का समर्थन करना आसान हो जाता है।

अन्यथा यदि यह ऐप आम जनता द्वारा उपभोग किया जाता है और उपयोगकर्ता के अनुकूल माना जाता है तो दूसरी विधि बेहतर है। क्षमा करें, लेकिन मुझे वास्तव में ऐसा करने का एक छोटा तरीका नहीं पता है।

यदि यह ऐप केवल आपकी कंपनी द्वारा आंतरिक रूप से उपभोग करने के लिए है, तो शॉर्टकट "item(s)"काम करें। Enterprisy कोड लिखते समय आपको वास्तव में किसी को प्रभावित नहीं करना है। लेकिन मैं सार्वजनिक रूप से उपभोग किए गए ऐप के लिए ऐसा करने के खिलाफ सलाह दूंगा क्योंकि इससे यह आभास होता है कि प्रोग्रामर आलसी है और इस तरह ऐप की गुणवत्ता के बारे में उनकी राय कम है। मेरा विश्वास करो, इस मामले की तरह छोटी चीजें।


35
जबकि मैं इस आधार से सहमत हूं, आप उन भाषाओं की अनदेखी कर रहे हैं जिनमें बहुलता की दो डिग्री से अधिक है। (उदाहरण के लिए रूसी को लें। इसके 1, <5, या> = 5 के आधार पर कहने के तीन अलग-अलग तरीके और यहां तक ​​कि यह निर्भर करता है कि आप वास्तव में किस बारे में बात कर रहे हैं)। मूल रूप से मैं कह रहा हूं कि आपको एक मजबूत सशर्त बयान की जरूरत है न कि सिर्फ एक टर्नरी ऑपरेटर की।
9

4
आप noofitemsselectedपहले विकल्प के लिए इस उदाहरण में दूर का अनुकूलन भी कर सकते हैं ; चूँकि आप जानते हैं कि यह 1. है
डिफ़ॉल्ट

16
जब हम इस पर होते हैं, तो हिब्रू में 1, 2, 3-10 और 11+ के लिए अलग-अलग बहुवचन हो सकते हैं।
योएल Spolsky

3
@ योएल, हिब्रू में कई अलग-अलग बहुवचन हो सकते हैं? לא ילעתי (मुझे नहीं पता)! आधुनिक हिब्रू अंग्रेजी की तरह है, जहाँ तक प्लुरल जाते हैं (हालाँकि प्राचीन हिब्रू में भी एक दोहरा रूप था।)
केन ब्लूम

3
अंग्रेजी में, शून्य को बहुवचन (0 आइटम, 2 आइटम) की तरह माना जाता है; हिब्रू, रूसी, रोमानियाई में शून्य के साथ क्या होता है? क्या श्रेणियों की पहचान करने का एक सरल तरीका है? मैं अनुमान लगा रहा हूं कि जानकारी प्रति भाषा निर्धारित की जानी है, इसलिए संदेश फ़ाइलों पर आधारित किसी भी प्रणाली को संदेशों के एक समूह में बहुलता की अलग-अलग मात्रा से निपटना पड़ता है। आउच! अनुवाद स्थापित करना भी मुश्किल होगा - विभिन्न भाषाओं के लिए अलग-अलग संदेशों की आवश्यकता होती है।
जोनाथन लेफ़लर 6

94

आप बिना किसी संदेश के केवल वस्तुओं को हटाकर और उपयोगकर्ता को वास्तव में अच्छी सुविधा प्रदान करके इस गंदी बहुलता से बच सकते हैं। यूजर्स ने कभी कुछ नहीं पढ़ा । आप वैसे भी अपने कार्यक्रम के हिस्से के रूप में एक अच्छी पूर्ववत सुविधा का निर्माण करें

जब आप एक पूर्ववत सुविधा का निर्माण करते हैं तो आपको वास्तव में 2 लाभ मिलते हैं। पहला लाभ उपयोगकर्ता की ज़िंदगी को उसकी गलतियों को उलटने और पढ़ने को कम करने की अनुमति देकर आसान बनाता है। दूसरा लाभ यह है कि आपका ऐप गैर-तुच्छ वर्कफ़्लो (केवल गलतियाँ नहीं) को उलटने की अनुमति देकर वास्तविक जीवन को प्रतिबिंबित कर रहा है।

मैंने एक बार एक संवाद या पुष्टिकरण संदेश का उपयोग किए बिना एक ऐप लिखा था। इसने कुछ गंभीर सोच ली और पुष्टि-प्रकार के संदेशों का उपयोग करने की तुलना में इसे लागू करना काफी कठिन था। लेकिन अंतिम परिणाम इसके अंतिम-उपयोगकर्ताओं के अनुसार उपयोग करने के लिए अच्छा था।


12
किसी कारण के लिए, मुझे वास्तव में ऐसा लगता है कि मैं इससे सहमत हूं और इसे बढ़ा देना चाहिए।
कोड़ी ग्रे

4
@ Theyvind, यहां बताया गया है: सत्यापन के लिए उपयोगकर्ता से पूछते हुए संदेश उपयोगकर्ता के लिए महंगे हैं, खासकर जब उन्हें एक मॉडल संवाद बॉक्स के रूप में प्रस्तुत किया जाता है जो उपयोगकर्ता द्वारा संवाद का जवाब देने तक सब कुछ रोक देता है । यह कई उपयोगकर्ताओं को इस बात से रूबरू कराता है कि वे संवाद बॉक्स के पिछले हिस्से को प्राप्त करने के लिए किसी भी बटन पर क्लिक करना शुरू करते हैं (आपने अभी कितने , अगले, अगले? ) पर क्लिक किया है । नतीजतन, यह अधिक सुरक्षित है, और उपयोगकर्ता कम घर्षण है, अगर आप बस एक नरम हटाते हैं, और एक पूर्ववत क्षमता प्रदान करते हैं। जीमेल इस तकनीक का बहुत प्रभाव डालता है।
रॉबर्ट हार्वे

5
डिबेटेबल, लेकिन किसी भी स्थिति में, डिलीट होने पर कन्फर्मेशन मैसेज के अलावा अन्य मामलों में भी यही समस्या आएगी, इसलिए यह जवाब वास्तव में प्रश्न के लिए बहुत ही महत्वपूर्ण है।
जे

50
मैंने इसे पढ़े बिना ही इसे उकेरा। मैं इसे हमेशा बाद में पूर्ववत कर सकता हूं
स्टीवन ए। लोव

6
@ रोर्बर्ट हार्वे: संभवतः एपोक्रीफाल, लेकिन कई साल पहले मैंने पढ़ा कि लोटस ने मैक के लिए लोटस नोट्स की 40,000 इकाइयां भेज दी थीं और 60,000 वापस कर दिए गए थे। इंटरफ़ेस इतना खराब था कि पायरेटेड लोगों ने भी इसे वापस भेज दिया।
डंकन

39

कैसे बस के बारे में:

string message = "Are you sure you want to delete " + noofitemsselected + " item(s)?"

इस तरह, आप संख्या समझौते की कठिनाइयों को समाप्त करते हैं, और बोनस के रूप में उपयोगकर्ता के लिए एक और भी छोटे, अधिक-टू-द-पॉइंट त्रुटि संदेश के साथ समाप्त होते हैं। हम सभी जानते हैं कि उपयोगकर्ता वैसे भी त्रुटि संदेश नहीं पढ़ते हैं । वे जितने छोटे होते हैं, उतनी ही कम से कम वे पाठ पर नज़र डालते हैं

या, इस ज्ञान से लैस है कि उपयोगकर्ता त्रुटि संदेश नहीं पढ़ते हैं, आप इसे अलग तरीके से देख सकते हैं। पुष्टिकरण संदेश को पूरी तरह से छोड़ दें, और बस एक पूर्ववत सुविधा प्रदान करें जो कि हटाए गए की परवाह किए बिना बस काम करता है। अधिकांश उपयोगकर्ता पहले से ही एक ऑपरेशन को पूर्ववत करने के आदी हैं जब वे नोटिस करते हैं कि यह वह नहीं था जो वे चाहते थे, और एक और कष्टप्रद पॉप-अप से निपटने की तुलना में इस व्यवहार को अधिक स्वाभाविक पाया जा सकता है।


1
अच्छा उत्तर। हालांकि, इस मामले में ग्राहक से कई मामलों के लिए त्रुटि संदेश प्रदान करने का अनुरोध किया गया था क्योंकि उन्हें लगा कि यह सबसे अच्छा तरीका है। लेकिन पाठ को बदलने से समस्या कम से कम हो सकती है और इसे कम गड़बड़ बना सकती है।
10yvind Bråthen

@ Øyvind: काफी साफ है। चूँकि आपको ग्राहक का अनुसरण करना है, मैं या तो पहले दृष्टिकोण का प्रस्ताव रखूँगा या एक हैंडलर फ़ंक्शन के साथ संसाधन फ़ाइल का उपयोग करूँगा। मुझे लगा कि यह एक विकल्प को इंगित करने के लायक है क्योंकि यह इतनी आसानी से भूल गया है। हेक, मैंने अपनी पहली प्रतिक्रिया प्रस्तुत करने के बाद तक भी इसके बारे में नहीं सोचा था।
कोड़ी ग्रे

विकल्प का सबसे अधिक स्वागत है। इसलिए मैंने इसे एक +1 दिया :)
Bryvind Bråthen

1
एक बेकार समस्या को हल करने की कोशिश नहीं करने के लिए +1। और स्टीव क्रुग का नियम याद रखें: आधे शब्दों को हटा दें। तो फिर से करें। मैं उपयोग करता हूं: "{x} आइटम हटाएं?"
सर्ज वेटियर

20

जावा के बारे में वर्षों से क्या है: java.text.MessageFormat और ChoiceFormat? अधिक जानकारी के लिए http://download.oracle.com/javase/1.4.2/docs/api/java/text/MessageFormat.html देखें ।

MessageFormat form = new MessageFormat("The disk \"{1}\" contains {0}.");
form.applyPattern(
   "There {0,choice,0#are no files|1#is one file|1<are {0,number,integer} files}.");

Object[] testArgs = {new Long(12373), "MyDisk"};

System.out.println(form.format(testArgs));

// output, with different testArgs
output: The disk "MyDisk" are no files.
output: The disk "MyDisk" is one file.
output: The disk "MyDisk" are 1,273 files.

आपके मामले में आप कुछ सरल चाहते हैं:

MessageFormat form = new MessageFormat("Are you sure you want to delete {0,choice,1#one item,1<{0,number.integer} files}?");

इस दृष्टिकोण का लाभ यह है कि यह i18n बंडलों के साथ अच्छी तरह से काम करता है, और आप भाषाओं के लिए ठीक से अनुवाद प्रदान कर सकते हैं (जैसे जापानी) जिसमें बहुवचन या एकवचन शब्दों की कोई अवधारणा नहीं है।


1
यह दृष्टिकोण बहुलता को संभालने के लिए अच्छी तरह से काम करता है, लेकिन लिंग को दुखी नहीं करता है। आपको प्रत्येक प्रकार की चीज़ के लिए एक अलग स्ट्रिंग की आवश्यकता होती है जिसे हटाया जा सकता है।
श्री चमकदार और नई 安

यदि आप संज्ञा जानते हैं, तो आप उचित विशेषण के साथ काम करने के लिए वाक्यों को फैशन कर सकते हैं। लेकिन हाँ, शास्त्रीय ग्रीक का अध्ययन करने के बाद, आपके पास पुल्लिंग, स्त्रीलिंग, या नपुंसक संज्ञाओं के आधार पर शब्द का एक अलग रूप है (विशेषण उस संज्ञा के रूप को लेता है जो इसे संशोधित करता है), और वाक्य में इसके कार्य के आधार पर रूप भिन्न होता है ( विषय, वस्तु आदि)। हम हमेशा ऐसे मामलों के साथ आ सकते हैं जहां एक समाधान काम करता है और दूसरा नहीं। इस तरह से जावा लोगों ने समस्या को हल करने का प्रयास किया। आप अभी भी जिस तरह से आप संदेश प्रारूप बनाने के साथ सावधान रहना होगा।
बेरिन लोरिट्श

आप हमेशा जावा समाधान को दो पूर्णांक खिला सकते हैं, जहां दूसरा एक लिंग इंगित करता है। (लेकिन वास्तव में, लिंग समझौता आमतौर पर एक चिंता का विषय है, क्योंकि एक संदेश में विभिन्न वस्तुओं को फिट करने का उपयोग एक वस्तु में एक ही वस्तु की विभिन्न संख्याओं को फिट करने की तुलना में कम अक्सर होता है)
केन ब्लूम

12

मैं संदेश को हार्डकोड नहीं कर रहा था, लेकिन एक अलग संसाधन फ़ाइल में दो संदेश प्रदान कर रहा था। पसंद

string DELETE_SINGLE = "You have selected {0} item. Are you sure you want to delete it?";
string DELETE_MULTI = "You have selected {0} items. Are you sure you want to delete them?";

और फिर उन्हें String.Format की तरह खिलाना

if(noofitemsselected == 1)
    messageTemplate = MessageResources.DELETE_SINGLE;
else
    messageTemplate = MessageResources.DELETE_MULTI;

string message = String.Format(messageTemplate, noofitemsselected)

मुझे लगता है कि इस दृष्टिकोण को स्थानीय बनाना और बनाए रखना आसान है। सभी UI संदेश एक ही स्थान पर होंगे।


+1, मुझे यह तरीका पसंद है। हालाँकि, आपको संसाधन नाम समकक्षों का ट्रैक रखने की आवश्यकता होगी।
डिफ़ॉल्ट

11

आप संदेश को पूरी तरह से अलग करके समस्या को पूरी तरह से दरकिनार कर सकते हैं।

string message = "The number of selected items is " + noofitemsselected + ". Are you sure you want to delete everything in this selection?";

10

पहली चीज़ जो मैं सुझाता हूँ वह है: उपयोग string.Format। यह आपको ऐसा कुछ करने की अनुमति देता है:

int numOfItems = GetNumOfItems();
string msgTemplate;
msgTemplate = numOfItems == 1 ? "You selected only {0} item." : "Wow, you selected {0} items!";
string msg = string.Format(msgTemplate, numOfItems);

इसके अलावा, WPF ऐप्स में, मैंने ऐसे सिस्टम देखे हैं जहां एक संसाधन स्ट्रिंग को दो संदेशों के लिए पाइप-सीमांकित किया जाएगा: एक विलक्षण और एक बहुवचन संदेश (या एक शून्य / एकल / कई संदेश, यहां तक ​​कि)। एक कस्टम कनवर्टर का उपयोग इस संसाधन को पार्स करने और प्रासंगिक (स्वरूपित) स्ट्रिंग का उपयोग करने के लिए किया जा सकता है, इसलिए आपका Xaml कुछ इस तरह है:

<TextBlock Text="{Binding numOfItems, Converter={StaticResource c:NumericMessageFormatter}, ConverterParameter={StaticResource s:SuitableMessageTemplate}}" />

7

अंग्रेजी के लिए, ऊपर जवाब के बहुत सारे। अन्य भाषाओं के लिए यह अधिक कठिन है, क्योंकि बहुवचन संज्ञा के लिंग और शब्द के समाप्त होने पर निर्भर करते हैं। फ्रेंच में कुछ उदाहरण:

नियमित मर्दाना:

Vous avez choisi 1 compte. Voulez-vous vraiment le supprimer.
Vous avez choisi 2 comptes. Voulez-vous vraiment les supprimer.

नियमित स्त्री

Vous avez choisi 1 table. Voulez-vous vraiment la supprimer.
Vous avez choisi 2 tables. Voulez-vous vraiment les supprimer.

अनियमित मर्दाना ('एस' के साथ खत्म)

Vous avez choisi 1 pays. Voulez-vous vraiment le supprimer.
Vous avez choisi 2 pays. Voulez-vous vraiment les supprimer?

यही समस्या अधिकांश लैटिन भाषाओं में मौजूद है और जर्मन या रूसी में खराब हो जाती है, जहां 3 लिंग (मैकुलिन, स्त्री और नपुंसक) होते हैं।

यदि आपका उद्देश्य सिर्फ अंग्रेजी से अधिक संभालना है तो आपको ध्यान रखना होगा।


कम से कम मेरे मामले में, यह वास्तव में कोई समस्या नहीं है। प्रत्येक पाठ के लिए मैं संख्या सम्मिलित करना चाहता हूं, मुझे पता चल जाएगा कि स्ट्रिंग पैदा करते समय संज्ञा क्या है। लेकिन एक अधिक सामान्य समाधान बनाने के लिए मैं आपसे सहमत हूं, कि "सभी" भाषाओं के लिए काम करना मुश्किल हो सकता है, यदि असंभव कार्य नहीं है।
10yvind Bråthen

1
या पोलिश लें, जहाँ प्रयुक्त संज्ञा का बहुवचन रूप संख्या के आधार पर भिन्न होता है! : /
UpTheCreek

5

बहुवचन संदेशों को सक्षम करने के लिए जो कि ठीक से स्थानीयकरण करना संभव होगा, मेरी राय यह है कि पहले संख्या और संदेश के बीच अप्रत्यक्ष की एक परत बनाना बुद्धिमानी होगी।

उदाहरण के लिए, यह निर्दिष्ट करने के लिए कि आप कौन सा संदेश प्रदर्शित करना चाहते हैं, किसी प्रकार का एक निरंतर उपयोग करें। कुछ फ़ंक्शन का उपयोग करके संदेश प्राप्त करें जो कार्यान्वयन विवरण छिपाएंगे।

get_message(DELETE_WARNING, quantity)

अगला, एक शब्दकोश बनाएं जो संभव संदेश और विविधताएं रखता है, और विविधताओं को जानता है कि उनका उपयोग कब किया जाना चाहिए।

DELETE_WARNING = {
   1: 'Are you sure you want to delete %s item',
   >1: 'Are you sure you want to delete %s items'
   >5: 'My language has special plural above five, do you wish to delete it?'
}

अब आप केवल उस कुंजी को पा सकते हैं जो कि के अनुरूप है quantityऔर के मान को प्रक्षेपित करती हैquantity उस संदेश साथ ।

यह बड़ा और भोला उदाहरण है, लेकिन मैं वास्तव में ऐसा करने के लिए कोई अन्य समझदार तरीका नहीं देखता हूं और L10N और I18N के लिए अच्छा समर्थन प्रदान करने में सक्षम हूं।


5

आपको नीचे दिए गए फ़ंक्शन का अनुवाद VBA से C # करना होगा, लेकिन आपका उपयोग निम्न में बदल जाएगा:

int noofitemsselected = SomeFunction();
string message = Pluralize("You have selected # item[s]. Are you sure you want to delete [it/them]?", noofitemsselected);

मेरे पास एक वीबीए फ़ंक्शन है जो मैं एमएस एक्सेस में उपयोग करता हूं ठीक उसी तरह से करने के लिए जो आप बात कर रहे हैं। मुझे पता है कि मैं VBA पोस्ट करने के लिए टुकड़ों में हैक हो जाऊंगा, लेकिन यहाँ वैसे भी जाता है। एल्गोरिथ्म टिप्पणियों से स्पष्ट होना चाहिए:

'---------------------------------------------------------------------------------------'
' Procedure : Pluralize'
' Purpose   : Formats an English phrase to make verbs agree in number.'
' Usage     : Msg = "There [is/are] # record[s].  [It/They] consist[s/] of # part[y/ies] each."'
'             Pluralize(Msg, 1) --> "There is 1 record.  It consists of 1 party each."'
'             Pluralize(Msg, 6) --> "There are 6 records.  They consist of 6 parties each."'
'---------------------------------------------------------------------------------------'
''
Function Pluralize(Text As String, Num As Variant, Optional NumToken As String = "#")
Const OpeningBracket = "\["
Const ClosingBracket = "\]"
Const DividingSlash = "/"
Const CharGroup = "([^\]]*)"  'Group of 0 or more characters not equal to closing bracket'
Dim IsPlural As Boolean, Msg As String, Pattern As String

    On Error GoTo Err_Pluralize

    If IsNumeric(Num) Then
        IsPlural = (Num <> 1)
    End If

    Msg = Text

    'Replace the number token with the actual number'
    Msg = Replace(Msg, NumToken, Num)

    'Replace [y/ies] style references'
    Pattern = OpeningBracket & CharGroup & DividingSlash & CharGroup & ClosingBracket
    Msg = RegExReplace(Pattern, Msg, "$" & IIf(IsPlural, 2, 1))

    'Replace [s] style references'
    Pattern = OpeningBracket & CharGroup & ClosingBracket
    Msg = RegExReplace(Pattern, Msg, IIf(IsPlural, "$1", ""))

    'Return the modified message'    
    Pluralize = Msg
End Function

Function RegExReplace(SearchPattern As String, _
                      TextToSearch As String, _
                      ReplacePattern As String) As String
Dim RE As Object

    Set RE = CreateObject("vbscript.regexp")
    With RE
        .MultiLine = False
        .Global = True
        .IgnoreCase = False
        .Pattern = SearchPattern
    End With

    RegExReplace = RE.Replace(TextToSearch, ReplacePattern)
End Function

उपयोग उपरोक्त कोड टिप्पणियों में थोड़ा कट गया, इसलिए मैं इसे यहां दोहराऊंगा:

Msg = "There [is/are] # record[s]. [It/They] consist[s/] of # part[y/ies] each."

Pluralize(Msg, 1) --> "There is 1 record.  It consists of 1 party each."
Pluralize(Msg, 6) --> "There are 6 records.  They consist of 6 parties each."

हां, यह समाधान उन भाषाओं की उपेक्षा करता है जो अंग्रेजी नहीं हैं। चाहे वह मामला आपकी आवश्यकताओं पर निर्भर करता हो।


4

आप स्वचालित रूप से बहुवचन उत्पन्न कर सकते हैं, उदाहरण के लिए देखें। बहुवचन जनक

बहुवचन उत्पन्न करने वाले नियमों के लिए विकिपीडिया देखें

string msg = "Do you want to delete " + numItems + GetPlural(" item", numItems) + "?";

मुझे इस विधि का उपयोग करना पसंद है अगर आवेदन अंतर्राष्ट्रीयकरण नहीं है। एक और अधिक पॉलिश आवेदन में परिणाम के रूप में।
cspolton

1
इसका अंतर्राष्ट्रीयकरण करना वास्तव में कठिन है, और यह अक्सर अंग्रेजी में विफल रहता है जैसे "आपके पास आदेश हैं + numMice + GetPlural (" माउस ", numMice)"
जेम्स एंडरसन

@ जेम्स एंडरसन: अब, यह व्याकरणिक रूप से सबसे अच्छा उदाहरण नहीं है;; यह सोच के जाल में न पड़ें कि गेटप्यूरल विधि का उपयोग करना एकमात्र तरीका है जिसे आपको उपयोग करने की अनुमति है।
cspolton

कुछ और कोने के मामलों को संभालने के लिए कुछ और कार्यों के साथ युग्मित किया गया, मुझे लगता है कि यह एक बहुत अच्छा समाधान है, हालांकि कम नहीं।
लल्ली

4

अधिक सामान्य तरीके के बारे में कैसे। दूसरे वाक्य में बहुवचन से बचें:

हटाए जाने के लिए चयनित वस्तुओं की संख्या: noofitemsselected।
क्या आपको यकीन है?

मुझे पता चला है कि इसे इस तरह से करने से संख्या उस रेखा के अंत में आ जाती है जो वास्तव में आसान है। यह समाधान किसी भी भाषा में एक ही तर्क के साथ काम करेगा।


"हटाए जाने के लिए चयनित आइटम:" सही नहीं लगता है, वाक्य नामों की एक सूची को इंगित करता है, लेकिन एक संख्या मुद्रित होती है। भले ही "हटाए जाने वाली वस्तुओं की संख्या:" में बदल दिया गया हो, फिर भी "आइटम" अजीब है।
लल्ली

@ लल्ली: हाँ, शब्द सही नहीं है, और कोई भी समाधान सही नहीं है। मैं केवल इसे लेबल और मान जैसे फ़ॉर्म में डालने का सुझाव दे रहा हूं। आप जोड़ने के बारे में सही हैं Number(मैं अपने बच्चे को सोने के लिए रॉक करते समय जवाब दे रहा था)।
16

4

मेरा सामान्य दृष्टिकोण "एकल / बहुवचन समारोह" लिखना है, जैसे:

public static string noun(int n, string single, string plural)
{
  if (n==1)
    return single;
  else
    return plural;
}

तब संदेश के मुख्य भाग में मैं इस फ़ंक्शन को कॉल करता हूं:

string message="Congratulations! You have won "+n+" "+noun(n, "foobar", "foobars")+"!";

यह पूरी तरह से बेहतर नहीं है, लेकिन कम से कम यह, (ए) एक फ़ंक्शन में निर्णय लेता है और इसलिए कोड को थोड़ा अशुद्ध करता है, और (बी) अनियमित बहुवचन को संभालने के लिए पर्याप्त लचीला है। यानी संज्ञा (n, "बाल", "बच्चे") और इस तरह कहना काफी आसान है।

बेशक यह केवल अंग्रेजी के लिए काम करता है, लेकिन अवधारणा अधिक जटिल अंत वाली भाषाओं के लिए आसानी से विस्तार योग्य है।

यह मेरे लिए होता है कि आप अंतिम पैरामीटर को आसान मामले के लिए वैकल्पिक बना सकते हैं:

public static string noun(int n, string single, string plural=null)
{
  if (n==1)
    return single;
  else if (plural==null)
    return single+"s";
  else
    return plural;
}

1
मुझे आपका अंतिम भाग पसंद है जहां आप संज्ञा को बहुवचन देने के लिए s जोड़ने के डिफ़ॉल्ट ऑपरेशन के मामले में कोड को "अयोग्य" करने के लिए एक डिफ़ॉल्ट मान का उपयोग करते हैं ।
10yvind Bråthen

4

अंतर्राष्ट्रीयकरण

मुझे लगता है कि आप अंतर्राष्ट्रीयकरण का समर्थन चाहते हैं, इस मामले में विभिन्न भाषाओं में बहुवचन के लिए अलग-अलग पैटर्न होते हैं (जैसे किसी चीज़ के लिए एक विशेष बहुवचन रूप, या पोलिश जैसी अधिक जटिल भाषाएं), और आप अपने स्ट्रिंग के लिए कुछ सरल पैटर्न लागू करने पर भरोसा नहीं कर सकते। ठीक करना।

आप GNU गेटटेक्स्ट ngettextफ़ंक्शन का उपयोग कर सकते हैं और अपने स्रोत कोड में दो अंग्रेजी संदेश प्रदान कर सकते हैं । गेटटेक्स्ट अन्य भाषाओं में अनुवादित होने पर अन्य (संभवतः अधिक) संदेशों से चुनने के लिए बुनियादी ढांचा प्रदान करेगा। GNU गेटटेक्स्ट के बहुवचन समर्थन के पूर्ण विवरण के लिए http://www.gnu.org/software/hello/manual/gettext/Plural-forms.html देखें ।

GNU गेटटेक्स्ट LGPL के अंतर्गत है। गेटटेक्स्ट के C # पोर्ट में ngettextनाम GettextResourceManager.GetPluralStringहै।

(यदि आपको स्थानीयकरण समर्थन की आवश्यकता नहीं है, और तुरंत गेटटेक्स्ट का उपयोग नहीं करना चाहते हैं, तो अपना स्वयं का फ़ंक्शन लिखें जो अंग्रेजी के लिए ऐसा करता है, और इसके लिए दो पूर्ण संदेश पास करें , इस तरह यदि आपको बाद में l10n की आवश्यकता है, तो आप कर सकते हैं एकल फ़ंक्शन को फिर से लिखना।)


3

फ़ंक्शन के बारे में कैसे लिखें

string GetOutputMessage(int count, string oneItemMsg, string multiItemMsg)
{
 return string.Format("{0} {1}", count, count > 1 ? multiItemMsg : oneItemMsg);
}

.. और जरूरत पड़ने पर इसका इस्तेमाल करें?

string message = "You have selected " + GetOutputMessage(noofitemsselected,"item","items") + ". Are you sure you want to delete it/them?";

3
आपने इस बारे में नहीं सोचा कि आपने क्या किया था, आपके पास
गुणनखंडों

आपको इस फ़ंक्शन के पूरे वाक्य के लिए बस दो संदेश पास करने चाहिए।
केन ब्लूम

यह सिर्फ एक उदाहरण था। मुझे एहसास है कि पूरे वाक्यों को भेजने वाला संस्करण अधिक सही है।
पावेल मोरशेन्युक

3

पहली समस्या के लिए, मेरा मतलब है कि Pluralize, आप Inflector का उपयोग कर सकते हैं ।

और दूसरे के लिए, आप एक स्ट्रिंग प्रतिनिधित्व एक्सटेंशन का उपयोग कर सकते हैं जैसे कि ToPronounString।


3

हमारी टीम के एक सदस्य द्वारा कल मेरे सामने प्रस्तुत किया गया यह सटीक प्रश्न था।

चूंकि यह स्टैकऑवरफ्लो पर फिर से यहां आया, मुझे लगा कि ब्रह्मांड मुझे एक सभ्य समाधान का उत्पादन करने के लिए बैश होने के लिए कह रहा है।

मैं जल्दी से एक साथ कुछ डाल दिया है और यह सही नहीं है, लेकिन यह कुछ चर्चा / विकास का उपयोग या स्पार्क हो सकता है।

यह कोड इस विचार पर आधारित है कि 3 संदेश हो सकते हैं। शून्य आइटम के लिए एक, एक आइटम के लिए एक और एक से अधिक आइटम के लिए जो निम्न संरचना का पालन करते हैं:

singlePropertyName singlePropertyName_Zero
एकलप्रकारात्मक
नाम_प्रधान

मैंने संसाधन वर्ग की नकल करने के लिए परीक्षण करने के लिए एक आंतरिक वर्ग बनाया है। मैंने अभी तक वास्तविक संसाधन फ़ाइल का उपयोग करके इसका परीक्षण नहीं किया है, इसलिए मुझे पूर्ण परिणाम देखना अभी बाकी है।

यहाँ कोड है (वर्तमान में मैंने कुछ जेनेरिक को शामिल किया है जहाँ मुझे पता है कि मैं तीसरे परम को केवल एक प्रकार के रूप में निर्दिष्ट कर सकता हूं और दूसरा पैराम भी एक स्ट्रिंग है, मुझे लगता है कि इन दो मापदंडों को कुछ बेहतर में संयोजित करने का एक तरीका है, लेकिन मैं ' जब मेरे पास एक खाली पल होगा तो मैं वापस आऊंगा।

    public static string GetMessage<T>(int count, string resourceSingularName, T resourceType) where T : Type
{
    var resourcePluralName = resourceSingularName + "_Plural";
    var resourceZeroName = resourceSingularName + "_Zero";
    string resource = string.Empty;
    if(count == 0)
    {
        resource = resourceZeroName;
    }
    else{
        resource = (count <= 1)? resourceSingularName : resourcePluralName;
    }
    var x = resourceType.GetProperty(resource).GetValue(Activator.CreateInstance(resourceType),null);

    return x.ToString();
}

टेस्ट संसाधन वर्ग:

internal class TestMessenger
{
    public string Tester{get{
    return "Hello World of one";}}
    public string Tester_Zero{get{
    return "Hello no world";}}
    public string Tester_Plural{get{
    return "Hello Worlds";}}
}

और मेरी त्वरित निष्पादन विधि

void Main()
{
    var message = GetMessage(56, "Tester",typeof(TestMessenger));
    message.Dump();
}

यदि आप चाहते हैं कि यह वास्तव में पूर्ण हो, तो आपको singlePropertyName_Allइसे और अधिक स्पष्ट करने के लिए एक संदेश भी जोड़ना चाहिए ।
16

2

मेरे दृष्टिकोण से, आपका पहला समाधान सबसे अनुकूल है। मैं ऐसा क्यों कहता हूं कि यदि आपको कई भाषाओं का समर्थन करने के लिए आवेदन की आवश्यकता होती है, तो दूसरा विकल्प श्रमसाध्य हो सकता है। मुट्ठी दृष्टिकोण के साथ बहुत प्रयास के बिना पाठ को स्थानीय बनाना आसान है।


2

आप अधिक सामान्य संदेश के लिए जा सकते हैं जैसे 'क्या आप सुनिश्चित हैं कि आप चयनित आइटम हटाना चाहते हैं'।


3
यह निश्चित रूप से काम करता है, लेकिन मुझे लगता है कि एक नज़र में हटाए जाने के बारे में वस्तुओं की संख्या दिखाने के लिए विचारक का विचार एक अच्छा है। एक से अधिक बार, मैंने अपने डेस्कटॉप से ​​एक फ़ाइल को हटाने की कोशिश की है और गलती से उस एक फ़ाइल से अधिक हटा दी गई है।
कोड़ी ग्रे

2

मैं इस बात पर निर्भर करता हूं कि आपके पास कितना अच्छा संदेश है। सबसे आसान से लेकर सबसे कठिन:

  1. बहुवचन से बचने के लिए अपना त्रुटि संदेश पुनः लिखें। आपके उपयोगकर्ता के लिए उतना अच्छा नहीं है, लेकिन तेज़ है।

  2. अधिक सामान्य भाषा का उपयोग करें लेकिन फिर भी संख्या शामिल है।

  3. एक "बहुवचन" और विभक्ति प्रणाली एला रेल्स का उपयोग करें, ताकि आप कह सकें pluralize(5,'bunch')और प्राप्त कर सकें 5 bunches। इसके लिए पटरियों का एक अच्छा पैटर्न है।

  4. अंतर्राष्ट्रीयकरण के लिए, आपको यह देखना होगा कि जावा क्या प्रदान करता है। यह विभिन्न भाषाओं का समर्थन करेगा, जिनमें 2 या 3 वस्तुओं के साथ विशेषण के विभिन्न रूप शामिल हैं। "S" समाधान बहुत अंग्रेजी केंद्रित है।

आप किस विकल्प के साथ जाते हैं यह आपके उत्पाद लक्ष्यों पर निर्भर करता है। - एनडीपी


2

आप ऐसा संदेश क्यों देना चाहेंगे जिसे उपयोगकर्ता वास्तव में समझ सकें? यह 40 साल के इतिहास के कार्यक्रम के खिलाफ जाता है। Nooooo, हमारे पास एक अच्छी बात चल रही है, इसे समझने योग्य संदेशों के साथ खराब मत करो ।


(J / k)


+1: यहाँ भी कुछ हास्य देखने के लिए अच्छा है। लेकिन भले ही आप मजाक कर रहे हों, मैं आपके अंतर्निहित बिंदु को समझता हूं। वर्षों के दौरान बनाए गए कई कार्यक्रमों में बेहद खराब संदेश हैं। आमतौर पर क्योंकि वे एक सामान्य उपयोगकर्ता के लिए वैसे भी समझने के लिए तकनीकी का रास्ता पाते हैं।
10yvind Bråthen

अच्छी बात। मैं हमेशा इसे पसंद करता हूं जब मुझे "उपयोगकर्ता इनपुट पर त्रुटि 494-बी" जैसा संदेश मिलता है - यह उस अतिरिक्त छोटे रहस्य को जोड़ता है जो गलत है जो जीवन को बहुत अधिक रोचक बनाता है। मुझे हाल ही में एक पासवर्ड बनाने की कोशिश में एक त्रुटि मिली, जिसने बस कहा, "पासवर्ड सुरक्षा आवश्यकताओं को पूरा नहीं करता है"। कोई संकेत नहीं बस मुझे क्या आवश्यकता नहीं थी। मेरे पासवर्ड में ऊपरी और निचले मामले के अक्षर और कई अंक शामिल थे। मैंने एक धर्मनिरपेक्ष चरित्र जोड़ने की कोशिश की। अभी भी नहीं। यह आखिरकार तब पारित हुआ जब मैंने एक चरित्र का निर्माण किया। मुझे लगता है कि उनके पास एक नियम था कि आप एक ही पंक्ति में दो बार एक ही चरित्र नहीं रख सकते।
जय

2

यह Warcraft की दुनिया में किया जाता है जैसे:

BILLING_NAG_WARNING = "Your play time expires in %d |4minute:minutes;";


0

एक दृष्टिकोण जिसका मैंने उल्लेख नहीं किया है, वह एक प्रतिस्थापन / चयन टैग (जैसे कि "आप स्क्वैश के बारे में हैं [0} [? ({0} = 1): / कैक्टस / कैक्टि /]" का उपयोग करेंगे। (दूसरे शब्दों में, एक प्रारूप जैसी अभिव्यक्ति है कि तर्क शून्य के आधार पर प्रतिस्थापन निर्दिष्ट करें, पूर्णांक के रूप में लिया गया है, बराबर 1)। मैंने ऐसे टैग पहले के दिनों में उपयोग किए गए देखे हैं। मैं किसी भी बारे में नहीं जानता हूं। उनके लिए .net में मानक, और न ही मैं उन्हें प्रारूपित करने का सबसे अच्छा तरीका जानता हूं।


0

मुझे लगता है कि एक मिनट के लिए बॉक्स से बाहर हो जाएगा, यहां सभी सुझाव या तो बहुवचन हैं (और बहुवचन, लिंग, आदि के 1 से अधिक स्तर के बारे में चिंता करते हैं) या बिल्कुल भी उपयोग न करें और एक अच्छा पूर्ववत प्रदान करें।

मैं गैर-भाषिक तरीके से जाऊंगा और उसके लिए दृश्य कतारों का उपयोग करूंगा। उदाहरण के लिए, एक Iphone ऐप की कल्पना करें जो आप अपनी उंगली पोंछकर आइटम का चयन करते हैं। मास्टर डिलीट बटन का उपयोग करके उन्हें हटाने से पहले, यह चयनित वस्तुओं को "हिलाएगा" और आपको वी (ओके) या एक्स (रद्द) बटन के साथ एक प्रश्न चिह्न शीर्षक बॉक्स दिखाएगा ...

या, कीनकट / मूव / Wii की 3 डी दुनिया में - फाइलों को चुनने की कल्पना करें, अपने हाथ को डिलीट बटन पर ले जाएं और कहा जाए कि पुष्टि करने के लिए अपने सिर के ऊपर अपना हाथ घुमाएं (उसी दृश्य प्रतीकों का उपयोग करें जैसा कि मैंने पहले उल्लेख किया है। उदाहरण के लिए। यह पूछने के लिए कि आप 3 फ़ाइलों को हटा दें, यह आपको 3 फाइलें दिखाएगा जिसमें एक होवरिंग आधा पारदर्शी लाल X होगा और आपको पुष्टि करने के लिए कुछ करने के लिए कहा जाएगा।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.