Kullanıcı mesajlarında çokluk


106

Çoğu zaman, kullanıcıya gösterilecek mesajlar oluştururken, mesaj müşteriyi bilgilendirmek istediğim birkaç şey içerecektir .

Bir örnek vereceğim: Müşteri, 1 ve üzeri bir dizi öğe seçti ve sil'e tıkladı. Şimdi müşteriye bir onay mesajı vermek istiyorum ve bir grup öğeyi seçerek ve yalnızca birini silmek istediğinde sil'e tıklayarak hata yapma olasılığını en aza indirmek için seçtiği öğe sayısını belirtmek istiyorum. onları.

Bunun bir yolu, genel mesajı böyle yapmaktır:

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

Buradaki "sorun" noofitemselected1'in olduğu durumdur ve öğeler ve bunlar yerine öğeyi ve onu yazmamız gerekir .

Normal çözümüm böyle bir şey olacak

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

Kodun içindeki sayıların çoğuna çok sayıda referans varsa ve gerçek mesajın okunması zorlaşırsa, bu oldukça uzar ve oldukça çirkin bir şekilde gerçekten hızlı olur.

Yani sorularım basit. Bunun gibi mesajlar oluşturmanın daha iyi yolları var mı?

DÜZENLE

Mesajın bir mesaj kutusu içinde gösterilmesi gerektiğinden bahsettiğim ve mesaj kutusunu kullanmaktan nasıl kaçınılacağına dair bir cevap verdiğimde birçok kişinin çok takıldığını görüyorum ve bu çok iyi. .

Ancak çoğullaşma sorununun mesaj kutularına ek olarak programdaki diğer yerler için de geçerli olduğunu unutmayın. Örneğin, ızgarada seçilen çizgilerin sayısını gösteren bir ızgaranın yanındaki bir etiket, çoğullama ile ilgili aynı soruna sahip olacaktır.

Bu, temelde programlardan bir şekilde çıkarılan çoğu metin için geçerlidir ve sonra çözüm, programı artık metin çıktılmayacak şekilde değiştirmek kadar basit değildir :)


6
@ 0xA3: Her dilde "öğe (ler)" kadar kolay ifade edilebilen bir çoğullaşma olup olmadığını gerçekten bilmiyorum.
Jens

5
Muhtemelen yerelleştirme hakkında da düşünmelisiniz. Bu sorun çok daha kötüye gidebilir.
Alex Brown

4
@Jens: Mümkün olan en az uygun şekilde genellikle yapmazlar. Bazı diller örneğin 2-4 için 5-sonsuzluktan farklı çoğullamalara sahiptir, hepsi cinsiyete bağlıdır. "Doğal Diller: Yerelleştirme Çılgınlığı! Yakında size en yakın bir bilgisayara geliyor!"
Piskvor,

29
IMO, hiçbir şey programcıları kullanıcılara kötü çoğulluktan daha tembel gösteremez.
Greg

4
@ Øyvind: Düzenlemeniz için +1. Görünüşe göre buradaki "cevaplayıcıların" çoğu, doğru olan bir çözüm sunmak yerine, sorunuzun yanlış olduğunu kanıtlamaya daha çok niyetli. İsterseniz anti-çözümler.
mwolfe02

Yanıtlar:


53

Ne kadar küçük olursa olsun herhangi bir şans varsa, bu uygulamanın başka dillere çevrilmesi gerekecekse, o zaman ikisi de yanlıştır. Bunu yapmanın doğru yolu şudur:

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?"
);

Bunun nedeni, farklı dillerin çoğulluğu farklı şekilde ele almasıdır. Malay gibi bazılarının sözdizimsel çoğulları bile yoktur, bu nedenle dizeler genellikle aynı olur. İki dizeyi ayırmak, daha sonra diğer dilleri desteklemeyi kolaylaştırır.

Aksi takdirde, bu uygulamanın genel halk tarafından kullanılması amaçlanıyorsa ve kullanıcı dostu olması bekleniyorsa, ikinci yöntem tercih edilir. Üzgünüm ama bunu yapmanın daha kısa bir yolunu gerçekten bilmiyorum.

Bu uygulamanın yalnızca şirketiniz tarafından dahili olarak kullanılması amaçlanıyorsa, kısayol "item(s)"işini yapın. Girişimci kodu yazarken gerçekten kimseyi etkilemek zorunda değilsiniz. Ancak bunu herkese açık bir uygulama için yapmamanızı tavsiye ederim çünkü bu, programcının tembel olduğu izlenimini veriyor ve böylece uygulamanın kalitesi hakkındaki görüşlerini düşürüyor. Güven bana, bunun gibi küçük şeyler.


35
Öneriye katılıyorum, ancak siz iki dereceden fazla çoğulluğa sahip dilleri görmezden geliyorsunuz. (Örneğin Rusça'yı ele alalım. 1, <5 veya> = 5 olmasına ve hatta tam olarak ne hakkında konuştuğunuza bağlı olduğuna bağlı olarak üç farklı söylem şekli). Temel olarak, sadece üçlü bir operatöre değil, daha güçlü bir koşullu ifadeye ihtiyacınız olduğunu söylüyorum.
crasic

4
Hatta noofitemsselectedbu örnekteki ilk seçenek için optimize edebilirsiniz ; 1 olduğunu bildiğiniz için
Varsayılan

16
Biz oradayken, İbranice 1, 2, 3-10 ve 11+ için farklı çoğulluklara sahip olabilir.
Joel Spolsky

3
@Joel, İbranice pek çok farklı çoğulluğa sahip olabilir mi? דעת ידעתי (bilmiyordum)! Modern İbranice, çoğullar söz konusu olduğunda İngilizce gibidir ( eski İbranice de ikili bir biçime sahip olsa da)
Ken Bloom

3
İngilizcede sıfır, çoğul gibi ele alınır (0 öğe, 2 öğe); İbranice, Rusça, Romence'de sıfırla ne olur? Aralıkları belirlemenin basit bir yolu var mı? Bilginin dil bazında belirlenmesi gerektiğini tahmin ediyorum, bu nedenle mesaj dosyalarına dayalı herhangi bir sistem, bir mesaj dizisinde değişen miktarlarda çoğullukla uğraşmak zorundadır. Ah! Çevirileri ayarlamak da zor olabilir - farklı diller için farklı sayıda mesaja ihtiyaç vardır.
Jonathan Leffler

94

Öğeleri herhangi bir mesaj olmadan silerek ve kullanıcıya gerçekten iyi bir Geri Al özelliği vererek tüm bu dağınık çoğulluğun önüne geçebilirsiniz. Kullanıcılar asla hiçbir şey okumaz . Sen iyi bir geri alma tesisini inşa etmeliyiz zaten senin programının bir parçası olarak.

Kapsamlı bir Geri Al tesisi oluşturduğunuzda aslında 2 avantaj elde edersiniz. İlk fayda, kullanıcının hataları tersine çevirmesine ve okumayı en aza indirmesine izin vererek hayatını kolaylaştırır. İkinci fayda, uygulamanızın önemsiz olmayan iş akışının (yalnızca hataların değil) tersine çevrilmesine izin vererek gerçek hayatı yansıtmasıdır.

Bir keresinde tek bir iletişim kutusu veya onay mesajı kullanmadan bir uygulama yazmıştım. Biraz ciddi düşünmek gerekiyordu ve uygulanması, onay tipi mesajlar kullanmaktan çok daha zordu. Ancak sonuç, son kullanıcılarına göre oldukça güzeldi.


12
Bazı nedenlerden dolayı, buna gerçekten katıldığımı ve buna olumlu oy vermem gerektiğini hissediyorum.
Cody Grey

4
@ Øyvind, İşte nedeni: Kullanıcıdan doğrulama isteyen mesajlar, özellikle kullanıcı diyaloğu yanıtlayana kadar her şeyi durduran kalıcı bir iletişim kutusu biçiminde sunulduğunda kullanıcı için pahalıdır . Bu, birçok kullanıcıyı, iletişim kutusunu geçmek için herhangi bir düğmeyi tıklatmaya başladıkları noktaya kadar rahatsız eder ( sonra, sonra, sonra kaç tane yükleyiciye tıkladınız ? ). Sonuç olarak, yumuşak bir silme işlemi yaparsanız ve bir geri alma özelliği sağlarsanız, daha güvenlidir ve kullanıcı sürtünmesi çok daha az olur. Gmail bu tekniği harika bir etki için kullanır.
Robert Harvey

5
Tartışılabilir, ancak her durumda, bir silme işleminde onay mesajı dışındaki durumlarda aynı sorun ortaya çıkacaktır, bu nedenle bu cevap soruya gerçekten teğettir.
Jay

50
bunu okumadan oy verdim. daha sonra her zaman geri alabilirim
Steven A. Lowe

6
@Robert Harvey: Muhtemelen uydurma, ama yıllar önce Lotus'un Mac için 40.000 birim Lotus Notes gönderdiğini ve 60.000'inin iade edildiğini okudum. Arayüz o kadar kötüydü ki, onu korsanlar bile geri gönderdi.
Duncan

39

Peki ya sadece:

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

Bu şekilde, sayı anlaşması zorluklarını ortadan kaldırırsınız ve kullanıcı için bonus olarak daha da kısa, noktaya daha fazla hata mesajı alırsınız. Kullanıcıların zaten hata mesajlarını okumadıklarını hepimiz biliyoruz . Ne kadar kısa olursa, en azından metne bakma olasılıkları o kadar yüksektir .

Veya kullanıcıların hata mesajlarını okumadıkları bilgisiyle donanmış olarak, buna farklı bir şekilde yaklaşabilirsiniz. Onay mesajını tamamen atlayın ve neyin silinmiş olduğuna bakılmaksızın Just Works'ün bir geri alma özelliğini sağlayın. Çoğu kullanıcı, istedikleri gibi olmadığını fark ettiklerinde bir işlemi geri almaya alışmıştır ve bu davranışı başka bir can sıkıcı pop-up ile uğraşmaktan daha doğal bulmaları olasıdır.


1
İyi cevap. Ancak, bu durumda müşteri tarafından birçok durum için hata mesajları vermesi talep edildi çünkü en iyi yaklaşım olduğunu düşünüyordu. Ancak metni değiştirmek, en azından sorunu en aza indirebilir ve daha az karmaşık hale getirebilir.
Øyvind Bråthen

@ Øyvind: Yeterince adil. Müşteriyi takip etmeniz gerektiğinden, ya önerdiğim ilk yaklaşımı benimseyeceğim ya da işleyici işlevi olan bir Kaynaklar dosyası kullanacağım. Sadece bir alternatifi belirtmeye değer olduğunu düşündüm çünkü çok kolay unutulabilir. Heck, ilk cevabımı gönderene kadar bunu düşünmemiştim bile.
Cody Grey

Alternatiflere en çok açığız. Bu yüzden +1 de verdim :)
Øyvind Bråthen

1
Çözülemeyen bir sorunu çözmeye çalışmamak için +1. Ve Steve Krug'un yasasını hatırlayın: Kelimelerin yarısını kaldırın. Sonra tekrar yap. Ben kullanıyorum: "{x} öğe silinsin mi?"
Serge Wautier

20

Ya Java'nın yıllardır sahip olduğu şeye ne dersiniz: java.text.MessageFormat ve ChoiceFormat? Daha fazla bilgi için http://download.oracle.com/javase/1.4.2/docs/api/java/text/MessageFormat.html adresine bakın .

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.

Sizin durumunuzda biraz daha basit bir şey istiyorsunuz:

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

Bu yaklaşımın avantajı, i18n paketleriyle iyi çalışması ve çoğul veya tekil kelimeler kavramı olmayan diller (Japonca gibi) için doğru çeviriler sağlayabilmenizdir.


1
Bu yaklaşım çoğulluğun üstesinden gelmek için iyi çalışıyor, ancak ne yazık ki toplumsal cinsiyetle ilgilenmiyor. Silinebilecek her şey için farklı bir dizeye ihtiyacınız var.
Bay Parlak ve Yeni 安 宇

İsmi biliyorsanız, cümleleri uygun sıfatla çalışacak şekilde şekillendirebilirsiniz. Ama evet, klasik Yunanca çalıştıktan sonra, eril, dişil ya da nötr isimlere dayanan farklı bir kelime biçimine sahipsiniz (sıfat, değiştirdiği ismin biçimini alır) ve biçim, cümledeki işlevine göre farklılık gösterir ( konu, nesne vb.). Her zaman bir çözümün işe yaradığı ve diğerinin çalışmadığı durumlar bulabiliriz. Java halkının sorunu çözmeye çalışmasının yolu budur. Yine de mesaj formatlarını oluştururken dikkatli olmalısınız.
Berin Loritsch

Java çözümünü her zaman iki tam sayı besleyebilirsiniz; ikincisi cinsiyeti gösterir. (Ama gerçekte, cinsiyet anlaşması genellikle daha az endişe kaynağıdır çünkü bir mesaja farklı nesnelerin yerleştirilmesi, aynı nesnenin farklı sayılarını bir mesaja sığdırmaktan daha az sıklıkta)
Ken Bloom

12

Mesajı kodlamadan değil, ayrı bir Kaynak dosyasında iki mesaj sağlayarak giderdim. Sevmek

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?";

ve sonra onları String.Format gibi

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

string message = String.Format(messageTemplate, noofitemsselected)

Bu yaklaşımın yerelleştirilmesinin ve sürdürülmesinin daha kolay olduğunu düşünüyorum. Tüm UI mesajları tek bir yerde olacaktır.


+1, bu yaklaşımı beğendim. Yine de, kaynak adı eşdeğerlerini takip etmeniz gerekir.
Varsayılan

11

Mesajı farklı bir şekilde ifade ederek sorunu tamamen ortadan kaldırabilirsiniz.

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

10

Önereceğim ilk şey: kullanın string.Format. Bu, şuna benzer bir şey yapmanızı sağlar:

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

Dahası, WPF uygulamalarında, bir kaynak dizesinin iki mesaja sahip olacak şekilde boru ile sınırlandırıldığı sistemler gördüm: tekil ve çoğul mesaj (veya sıfır / tek / çok mesaj, hatta). Daha sonra bu kaynağı ayrıştırmak ve ilgili (biçimlendirilmiş) dizeyi kullanmak için özel bir dönüştürücü kullanılabilir, böylece Xaml'ınız şuna benzer:

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

7

İngilizce için yukarıda çok sayıda cevap var. Çoğullar ismin cinsiyetine ve kelime bitimine bağlı olduğundan, diğer diller için daha zordur. Fransızca'da bazı örnekler:

Düzenli erkeksi:

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

Düzenli kadınsı

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

Düzensiz erkeksi ('s' ile biter)

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

Aynı sorun çoğu Latin dilinde mevcuttur ve 3 cinsiyetin (makülin, dişil ve nötr) olduğu Almanca veya Rusça'da daha da kötüleşir.

Hedefiniz İngilizceden daha fazlasını ele almaksa, dikkatli olmanız gerekir.


En azından benim durumumda, bu gerçekten bir sorun değil. Numarayı eklemek istediğim her metin için, dizeyi oluştururken ismin ne olduğunu bileceğim. Ama daha genel bir çözüm yapmak için size katılıyorum, "tüm" diller için çalışmasını sağlamak imkansız değilse de çok zor olabilir.
Øyvind Bråthen

1
Veya kullanılan ismin çoğul halinin sayıya bağlı olarak farklı olduğu Lehçe alalım! : /
UpTheCreek

5

Doğru bir şekilde yerelleştirilebilecek çoğul mesajlara sahip olabilmek için, bence önce numara ile mesaj arasında bir dolaylı katman oluşturmak akıllıca olacaktır.

Örneğin, hangi mesajı görüntülemek istediğinizi belirtmek için bir çeşit sabit kullanın. İletiyi, uygulama ayrıntılarını gizleyecek bir işlev kullanarak getirin.

get_message(DELETE_WARNING, quantity)

Ardından, olası mesajları ve varyasyonları tutan bir sözlük oluşturun ve varyasyonların ne zaman kullanılması gerektiğini bilmesini sağlayın.

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?'
}

Şimdi basitçe karşılık gelen anahtarı bulabilir ve bu mesajın quantitydeğerini hesaplayabilirsiniz quantity.

Bu aşırı basitleştirilmiş ve saf örnek, ancak bunu yapmanın başka mantıklı bir yolunu gerçekten görmüyorum ve L10N ve I18N için iyi destek sağlayabiliyorum.


5

Aşağıdaki işlevi VBA'dan C #'ye çevirmeniz gerekecek, ancak kullanımınız şu şekilde değişecektir:

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

MS Access'te tam olarak bahsettiğiniz şeyi yapmak için kullandığım bir VBA işlevim var. VBA yayınlamak için parçalara ayrılacağımı biliyorum, ama yine de burada. Algoritma, yorumlardan anlaşılır olmalıdır:

'---------------------------------------------------------------------------------------'
' 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

Yukarıdaki kod yorumlarında kullanım biraz azaldı, bu yüzden burada tekrar edeceğim:

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."

Evet, bu çözüm İngilizce olmayan dilleri göz ardı ediyor. Bunun önemli olup olmadığı gereksinimlerinize bağlıdır.


4

Çoğulu otomatik olarak üretebilirsiniz, bkz. Ör. çoğul üreteç .

Çoğul üretim kuralları için bkz. Wikipedia

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

Uygulama uluslararasılaşmamışsa bu yöntemi kullanmayı seviyorum. Puralize etme, daha parlak bir uygulama ile sonuçlanır.
cspolton

1
Bunu uluslararasılaştırmak gerçekten zor ve İngilizce'de genellikle başarısız oluyor, örneğin "Emirleriniz var + numMice + GetPlural (" fare ", numMice)"
James Anderson

@James Anderson: Şimdi, gramer açısından en iyi örnek bu değil ;-) Kullanmanıza izin verilen tek yöntemin GetPural yöntemi olduğunu düşünme tuzağına düşmeyin .
cspolton

Birkaç tane daha köşe vakayı ele almak için birkaç işlevle birleştiğinde, bunun daha kısa değil, çok iyi bir çözüm olduğunu düşünüyorum.
lalli

4

Daha genel bir yola ne dersiniz? İkinci cümlede çoğullaştırmaktan kaçının:

Silinecek seçili öğe sayısı: noofitemsselected.
Emin misiniz?

Bunu bu şekilde yapmanın, sayıyı bulması gerçekten kolay olan satırın sonuna koyduğunu öğrendim. Bu çözüm, herhangi bir dilde aynı mantıkla çalışacaktır.


"Silinecek seçili öğeler:" kulağa doğru gelmiyor, cümle bir isim listesini gösteriyor, ancak bir numara yazdırılıyor. "Silinecek öğe sayısı:" olarak değiştirilse bile, yine de "öğeler" gariptir.
lalli

@lalli: Evet, ifade mükemmel değil ve sunulan çözümlerin hiçbiri kulağa mükemmel gelmiyor. Ben sadece onu etiket ve değer gibi bir biçimde koymanızı öneriyorum. Ekleme konusunda haklısın Number(bebeğimi uykuya sallarken cevap veriyordum).
Danosaure

4

Genel yaklaşımım, şöyle bir "tek / çoğul işlev" yazmaktır:

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

Sonra mesajın gövdesinde bu işlevi çağırıyorum:

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

Bu çok daha iyi değil, ama en azından (a) kararı bir işleve koyar ve bu nedenle kodu biraz düzleştirir ve (b) düzensiz çoğulları işlemek için yeterince esnektir. yani isim (n, "çocuk", "çocuklar") ve benzerlerini söylemek yeterince kolaydır.

Elbette bu sadece İngilizce için geçerli, ancak kavram, daha karmaşık sonları olan diller için kolayca genişletilebilir.

Bana öyle geliyor ki, son parametreyi kolay durum için isteğe bağlı yapabilirsiniz:

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
İsmi çoğullaştırmak için bir s eklemenin varsayılan işlemi durumunda, kodu "düzenli hale getirmek" için varsayılan bir değer kullandığınız son parçanızı seviyorum .
Øyvind Bråthen

4

Uluslararasılaştırma

Uluslararasılaştırma desteği istediğinizi varsayıyorum, bu durumda farklı diller çoğullar için farklı kalıplara sahiptir (örneğin, bir şeyin 2'si için özel bir çoğul biçim veya Lehçe gibi daha karmaşık diller) ve dizinize basit bir kalıp uygulamaya güvenemezsiniz. Tamir etmek için.

GNU Gettext'in ngettextişlevini kullanabilir ve kaynak kodunuzda iki İngilizce mesaj sağlayabilirsiniz. Gettext, diğer dillere çevrildiğinde diğer (potansiyel olarak daha fazla) mesajlar arasından seçim yapmak için altyapı sağlayacaktır. GNU gettext'in çoğul desteğinin tam açıklaması için http://www.gnu.org/software/hello/manual/gettext/Plural-forms.html adresine bakın .

GNU Gettext, LGPL'nin altındadır. Gettext'in C # bağlantı noktasında ngettextadlandırılır GettextResourceManager.GetPluralString.

(Yerelleştirme desteğine ihtiyacınız yoksa ve Gettext'i hemen kullanmak istemiyorsanız, bunu İngilizce için yapan kendi işlevinizi yazın ve ona iki tam mesaj iletin, bu şekilde daha sonra l10n'ye ihtiyacınız olursa, tek bir işlevi yeniden yazarak ekleyin.)


3

Gibi işlev yazmaya ne dersiniz?

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

.. ve ne zaman ihtiyacınız olursa kullanın?

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

3
bunu düşünmedin mi lol, cümle için çarpanları ayırmak için bir işlevin var mı, sonra bir "it / onları"
yazıyorsun

Bu işleve tüm cümle için sadece iki mesaj iletmelisiniz.
Ken Bloom

Bu sadece bir örnekti. Tüm cümleleri gönderme varyantının daha doğru olduğunun farkındayım.
Pavel Morshenyuk

3

İlk sorun için, ben pluralize Yani, kullanabilirsiniz Inflector .

İkincisi için, ToPronounString gibi bir adla bir dize temsil uzantısı kullanabilirsiniz.


3

Dün de aynı soruyu ekibimizin bir üyesi bana sormuştu.

Burada StackOverflow'da tekrar ortaya çıktığından beri, evrenin bana düzgün bir çözüm üretme konusunda bir darbe yapmamı söylediğini anladım.

Bir şeyi çabucak bir araya getirdim ve hiçbir şekilde mükemmel değil, ancak işe yarayabilir veya bir tartışma / geliştirme başlatabilir.

Bu kod, 3 mesaj olabileceği fikrine dayanmaktadır. Sıfır ürün için bir, bir öğe için bir ve aşağıdaki yapıyı takip eden birden fazla öğe için bir:

singlePropertyName
singlePropertyName_Zero
singlePropertyName_Plural

Kaynak sınıfını taklit etmek için test etmek için dahili bir sınıf oluşturdum. Bunu henüz gerçek bir kaynak dosyası kullanarak test etmedim, bu yüzden henüz tam sonucu göremiyorum.

İşte kod (şu anda üçüncü paramı bir Tür olarak belirtebileceğimi bildiğim bazı jenerikleri ekledim ve ayrıca ikinci param bir dizedir, bu iki parametreyi daha iyi bir şeye birleştirmenin bir yolu olduğunu düşünüyorum ama ben '' Boş zamanım olduğunda buna geri döneceğim.

    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();
}

Test kaynak sınıfı:

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";}}
}

ve benim hızlı yürütme yöntemim

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

Bunun gerçekten eksiksiz olmasını istiyorsanız, singlePropertyName_Allbunu daha da belirgin hale getirmek için bir mesaj da eklemelisiniz .
Danosaure

2

Benim açımdan, ilk çözümünüz en uygun olanıdır. Neden şunu söylüyorum, uygulamanın birden çok dili desteklemesi durumunda ikinci seçenek zahmetli olabilir. İlk yaklaşımla, fazla çaba sarf etmeden metni yerelleştirmek kolaydır.


2

'Seçili öğeleri silmek istediğinizden emin misiniz' gibi daha genel bir mesaja gidebilirsiniz.


3
Bu kesinlikle işe yarıyor, ancak soran kişinin silinmek üzere olan öğelerin sayısını bir bakışta gösterme fikrinin iyi bir fikir olduğunu düşünüyorum. Birden çok kez masaüstümden bir dosyayı silmeye çalıştım ve yanlışlıkla birden fazla dosyayı sildim.
Cody Gray

2

Ne kadar güzel bir mesaj almak istediğine bağlıyım. En kolaydan en zora:

  1. Çoğullaşmayı önlemek için hata mesajınızı yeniden yazın. Kullanıcınız için güzel değil, daha hızlı.

  2. Daha genel bir dil kullanın ancak yine de sayıları dahil edin.

  3. "Çoğullaştırma" ve saptırma sistemi ala Rails kullanın, böylece söyleyip pluralize(5,'bunch')alabilirsiniz 5 bunches. Rayların bunun için iyi bir modeli var.

  4. Uluslararasılaştırma için Java'nın ne sağladığına bakmanız gerekir. Bu, 2 veya 3 maddeli farklı sıfat biçimlerine sahip olanlar da dahil olmak üzere çok çeşitli dilleri destekleyecektir. "S" çözümü oldukça İngilizce merkezlidir.

Hangi seçeneği tercih edeceğiniz, ürün hedeflerinize bağlıdır. - ndp


2

Kullanıcıların gerçekten anlayabileceği bir mesajı neden sunmak istersiniz? 40 yıllık programlama geçmişine aykırı. Nooooo, devam eden iyi bir şeyimiz var, anlaşılır mesajlarla onu bozma .


(j / k)


+1: burada da biraz mizah görmek güzel. Ama şaka yapıyor olsanız bile temel noktanızı anlıyorum. Yıllar boyunca oluşturulan birçok programın son derece kötü mesajları vardır. Genellikle normal bir kullanıcının anlayabileceği teknik bir yol buldukları için.
Øyvind Bråthen

İyi bir nokta. "Kullanıcı girdisinde Hata 494-B" gibi bir mesaj aldığımda onu her zaman seviyorum - hayatı çok daha ilginç kılan neyin yanlış olduğuna dair ekstra küçük gizemi ekliyor. Geçenlerde bir parola oluşturmaya çalışırken basitçe "Parola güvenlik gereksinimlerini karşılamıyor" şeklinde bir hata aldım. Hangi şartı karşılamadığıma dair ipucu yok. Parolam hem büyük hem de küçük harfler ve birkaç rakam içeriyordu. Sektörel bir karakter eklemeyi denedim. Hala hayır. Sonunda bir karakteri SİLDİĞİMDE geçti. Sanırım aynı karakteri iki kez üst üste kullanamayacağınıza dair bir kuralları vardı.
Jay

2

World of Warcraft'ta olduğu gibi yapın:

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

0

Biraz daha kısalıyor

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

0

Bahsettiğim görmediğim bir yaklaşım, bir değiştirme / seçme etiketinin kullanılmasıdır (ör. "{0} [? İ ({0} = 1): / cactus / cacti /]" gibi bir şey. (başka bir deyişle, formata benzer bir ifadeye sahip olmak, bağımsız değişkenin sıfır olup olmadığına bağlı olarak değiştirmeyi belirtin, 1'e eşittir) .net'ten önceki günlerde bu tür etiketlerin kullanıldığını gördüm; hiçbirinin farkında değilim onlar için standart .net, ne de onları biçimlendirmenin en iyi yolunu bilmiyorum.


0

Bir dakikalığına kutunun dışında düşünürdüm, buradaki tüm öneriler ya çoğullaştırmayı yapmak (ve birden fazla çoğullaştırma, cinsiyet vb. İçin endişelenmek) ya da hiç kullanmamak ve güzel bir geri alma sağlamaktır.

Dilsel olmayan yoldan gider ve bunun için görsel kuyruklar kullanırdım. Örneğin, parmağınızı silerek öğeleri seçtiğiniz bir Iphone uygulaması hayal edin. Ana silme düğmesini kullanarak bunları silmeden önce, seçilen öğeleri "sallayacak" ve size V (ok) veya X (iptal) düğmeleriyle birlikte soru işareti başlıklı bir kutu gösterecektir ...

Veya Kinekt / Move / Wii'nin 3B dünyasında - dosyaları seçtiğinizi, elinizi sil düğmesine hareket ettirdiğinizi ve onaylamak için elinizi başınızın üzerine getirmenizin söyleneceğini hayal edin (daha önce bahsettiğim aynı görsel sembolleri kullanarak. 3 dosyayı silmenizi mi istiyorsunuz? Bu size, üzerinde yarım şeffaf kırmızı X bulunan 3 dosya gösterecek ve onaylamak için bir şeyler yapmanızı söyleyecektir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.