Wielokrotnie, podczas generowania wiadomości do pokazania użytkownikowi, wiadomość będzie zawierała szereg rzeczy , o których chcę poinformować klienta.
Podam przykład: klient wybrał kilka pozycji od 1 wzwyż i kliknął Usuń. Teraz chcę przekazać klientowi wiadomość potwierdzającą i chcę wspomnieć o liczbie wybranych przez niego pozycji, aby zminimalizować możliwość popełnienia błędu przez wybranie kilku pozycji i kliknięcie przycisku Usuń, gdy chce usunąć tylko jedną z im.
Jednym ze sposobów jest utworzenie ogólnej wiadomości w ten sposób:
int noofitemsselected = SomeFunction();
string message = "You have selected " + noofitemsselected + " item(s). Are you sure you want to delete it/them?";
"Problemem" jest tutaj przypadek, w którym noofitemselected
jest 1 i musimy wpisać item i to zamiast itemów i je .
Moje normalne rozwiązanie będzie takie
int noofitemsselected = SomeFunction();
string message = "You have selected " + noofitemsselected + " " + (noofitemsselected==1?"item" : "items") + ". Are you sure you want to delete " + (noofitemsselected==1?"it" : "them") + "?";
Robi się to dość długo i dość paskudnie, naprawdę szybko, jeśli w kodzie jest wiele odniesień do mnogości liczb, a rzeczywista wiadomość staje się trudna do odczytania.
Więc moje pytania są proste. Czy są jakieś lepsze sposoby generowania takich wiadomości?
EDYTOWAĆ
Widzę, że wiele osób bardzo się rozłączyło w przypadku, gdy wspomniałem, że wiadomość powinna być wyświetlana w skrzynce wiadomości i po prostu udzieliła odpowiedzi, jak w ogóle uniknąć korzystania z tej skrzynki i to wszystko jest w porządku .
Pamiętaj jednak, że problem liczby mnogiej dotyczy również tekstów innych miejsc w programie oprócz okien komunikatów. Na przykład etykieta obok siatki wyświetlającej liczbę linii wybranych w siatce będzie miała ten sam problem dotyczący liczby mnogiej.
Zasadniczo dotyczy to większości tekstu, który jest w jakiś sposób generowany przez programy, a wtedy rozwiązanie nie jest tak proste, jak po prostu zmienić program tak, aby nie wyświetlał już tekstu :)
źródło
Odpowiedzi:
Jeśli kiedykolwiek będzie jakaś szansa, nieważne jak mała, że ta aplikacja będzie musiała zostać przetłumaczona na inne języki, to obie są w błędzie. Prawidłowy sposób to:
Dzieje się tak, ponieważ różne języki różnie obsługują wiele. Niektóre, takie jak malajski, nie mają nawet składniowej liczby mnogiej, więc ciągi znaków byłyby zasadniczo identyczne. Oddzielenie dwóch ciągów ułatwia późniejszą obsługę innych języków.
W przeciwnym razie, jeśli ta aplikacja jest przeznaczona do użytku publicznego i ma być przyjazna dla użytkownika, preferowana jest druga metoda. Przepraszam, ale tak naprawdę nie znam krótszego sposobu na zrobienie tego.
Jeśli ta aplikacja ma być używana tylko wewnętrznie przez Twoją firmę, zrób to na skróty
"item(s)"
. Nie musisz nikomu imponować, pisząc kod biznesowy. Ale odradzałbym to robić w przypadku aplikacji konsumowanej publicznie, ponieważ sprawia to wrażenie, że programista jest leniwy, a tym samym obniża jego opinię o jakości aplikacji. Zaufaj mi, takie małe rzeczy mają znaczenie.źródło
noofitemsselected
w tym przykładzie dla pierwszej opcji; ponieważ wiesz, że jest to 1.Możesz uniknąć całej tej niechlujnej mnogości, po prostu usuwając elementy bez żadnej wiadomości i dając użytkownikowi naprawdę dobrą funkcję Cofnij. Użytkownicy nigdy niczego nie czytają . W każdym razie powinieneś stworzyć dobrą funkcję Cofnij jako część swojego programu.
W rzeczywistości uzyskujesz 2 korzyści, tworząc kompleksową funkcję cofania. Pierwsza korzyść ułatwia życie użytkownika, umożliwiając mu odwracanie błędów i minimalizację czytania. Drugą korzyścią jest to, że Twoja aplikacja odzwierciedla prawdziwe życie, umożliwiając odwrócenie nietrywialnego przepływu pracy (a nie tylko błędów).
Kiedyś napisałem aplikację bez użycia jednego okna dialogowego lub wiadomości z potwierdzeniem. Wymagało to poważnego przemyślenia i było znacznie trudniejsze do wdrożenia niż używanie wiadomości typu potwierdzenia. Ale wynik końcowy był raczej przyjemny w użyciu, według jego użytkowników końcowych.
źródło
Może po prostu:
W ten sposób eliminujesz trudności z umową numeryczną i jako bonus otrzymujesz jeszcze krótszy, bardziej konkretny komunikat o błędzie dla użytkownika. Wszyscy wiemy, że użytkownicy i tak nie czytają komunikatów o błędach . Im są krótsze, tym bardziej prawdopodobne jest, że przynajmniej spojrzą na tekst.
Lub mając wiedzę, że użytkownicy nie czytają komunikatów o błędach, możesz podejść do tego inaczej. Pomiń całkowicie komunikat potwierdzający i po prostu zapewnij funkcję cofania, która po prostu działa, niezależnie od tego, co zostało usunięte. Większość użytkowników jest już przyzwyczajonych do cofania operacji, gdy zauważą, że nie jest to, czego chcieli, i prawdopodobnie uznają to zachowanie za bardziej naturalne niż konieczność radzenia sobie z kolejnym irytującym wyskakującym okienkiem.
źródło
A co z tym, co Java miała od lat: java.text.MessageFormat i ChoiceFormat? Więcej informacji można znaleźć pod adresem http://download.oracle.com/javase/1.4.2/docs/api/java/text/MessageFormat.html .
W twoim przypadku chcesz czegoś prostszego:
Zaletą tego podejścia jest to, że działa dobrze z pakietami i18n i możesz zapewnić prawidłowe tłumaczenia dla języków (takich jak japoński), które nie mają pojęcia liczby mnogiej ani liczby pojedynczej.
źródło
Postanowiłbym nie zakodować wiadomości na sztywno, ale podać dwie wiadomości w osobnym pliku zasobów. Lubić
a następnie umieszcza je w String.Format like
Myślę, że takie podejście jest łatwiejsze do zlokalizowania i utrzymania. Wszystkie komunikaty interfejsu użytkownika znajdowałyby się w jednym miejscu.
źródło
Możesz całkowicie ominąć ten problem, używając innego sformułowania wiadomości.
źródło
Pierwszą rzeczą, którą zasugerowałbym, jest: użyj
string.Format
. To pozwala zrobić coś takiego:Ponadto w aplikacjach WPF widziałem systemy, w których ciąg zasobów byłby rozdzielany potokiem, aby mieć dwie wiadomości: pojedynczą i mnogą (lub nawet zero / pojedynczą / wiele wiadomości). Następnie można użyć niestandardowego konwertera do przeanalizowania tego zasobu i użycia odpowiedniego (sformatowanego) ciągu, więc Xaml wygląda mniej więcej tak:
źródło
W przypadku języka angielskiego wiele odpowiedzi powyżej. W przypadku innych języków jest to trudniejsze, ponieważ liczba mnoga zależy od rodzaju rzeczownika i końcówki słowa. Kilka przykładów w języku francuskim:
Zwykły męski:
Zwykła kobieca
Nieregularny rodzaj męski (kończy się na „s”)
Ten sam problem występuje w większości języków łacińskich i nasila się w języku niemieckim lub rosyjskim, gdzie występują 3 rodzaje (maculine, żeński i nijaki).
Musisz uważać, jeśli Twoim celem jest opanowanie czegoś więcej niż tylko angielskiego.
źródło
Aby móc mieć wiadomości w liczbie mnogiej, które będzie można poprawnie zlokalizować, uważam, że rozsądnie byłoby najpierw utworzyć warstwę pośrednią między liczbą a wiadomością.
Na przykład użyj jakiejś stałej, aby określić, którą wiadomość chcesz wyświetlić. Pobierz wiadomość, używając funkcji, która ukryje szczegóły implementacji.
Następnie utwórz słownik zawierający możliwe komunikaty i odmiany, a następnie poinformuj o nich, kiedy należy ich użyć.
Teraz możesz po prostu znaleźć klucz, który odpowiada the
quantity
i interpolować wartośćquantity
z tą wiadomością.To zbyt uproszczony i naiwny przykład, ale tak naprawdę nie widzę innego rozsądnego sposobu, aby to zrobić i móc zapewnić dobre wsparcie dla L10N i I18N.
źródło
Będziesz musiał przetłumaczyć poniższą funkcję z VBA na C #, ale twoje użycie zmieniłoby się na:
Mam funkcję VBA, której używam w MS Access, aby robić dokładnie to, o czym mówisz. Wiem, że zostanę zhakowany na kawałki za publikowanie VBA, ale tak czy inaczej. Algorytm powinien wynikać z komentarzy:
Użycie zostało nieco odcięte w komentarzach do kodu powyżej, więc powtórzę to tutaj:
Tak, to rozwiązanie ignoruje języki inne niż angielski. To, czy to ma znaczenie, zależy od Twoich wymagań.
źródło
Możesz wygenerować liczbę mnogą automatycznie, patrz np. generator liczby mnogiej .
Aby zapoznać się z regułami generowania liczby mnogiej, zobacz wikipedię
źródło
Co powiesz na bardziej ogólny sposób. Unikaj liczby mnogiej w drugim zdaniu:
Dowiaduję się, że robiąc to w ten sposób, numer jest umieszczany na końcu linii, co jest naprawdę łatwe do wykrycia. To rozwiązanie działałoby z tą samą logiką w dowolnym języku.
źródło
Number
(odpowiadałem, kołysząc moje dziecko do snu).Moje ogólne podejście polega na napisaniu „funkcji pojedynczej / mnogiej”, na przykład:
Następnie w treści wiadomości nazywam tę funkcję:
Nie jest to o wiele lepsze, ale przynajmniej (a) umieszcza decyzję w funkcji, dzięki czemu trochę porządkuje kod, a (b) jest wystarczająco elastyczne, aby obsługiwać nieregularne liczby mnogie. tzn. łatwo jest powiedzieć rzeczownik (n, „dziecko”, „dzieci”) i tym podobne.
Oczywiście działa to tylko w przypadku języka angielskiego, ale koncepcję można łatwo rozszerzyć na języki z bardziej złożonymi zakończeniami.
Wydaje mi się, że ostatni parametr można ustawić jako opcjonalny dla łatwego przypadku:
źródło
Umiędzynarodowienie
Zakładam, że chcesz obsługiwać internacjonalizację, w którym to przypadku różne języki mają różne wzorce dla liczby mnogiej (np. Specjalna forma liczby mnogiej dla 2 czegoś lub bardziej skomplikowane języki, takie jak polski) i nie możesz polegać na zastosowaniu prostego wzoru do swojego ciągu naprawić to.
Możesz użyć funkcji GNU Gettext i umieścić
ngettext
w kodzie źródłowym dwie wiadomości w języku angielskim. Gettext zapewni infrastrukturę do wyboru spośród innych (potencjalnie więcej) wiadomości po przetłumaczeniu na inne języki. Zobacz http://www.gnu.org/software/hello/manual/gettext/Plural-forms.html, aby uzyskać pełny opis obsługi liczby mnogiej GNU gettext.GNU Gettext jest na licencji LGPL.
ngettext
jest nazwanyGettextResourceManager.GetPluralString
w porcie C # Gettext.(Jeśli nie potrzebujesz obsługi lokalizacji i nie chcesz od razu używać Gettext, napisz własną funkcję, która robi to dla języka angielskiego i prześlij do niej dwie pełne wiadomości , w ten sposób, jeśli będziesz potrzebować l10n później, możesz dodaj, przepisując pojedynczą funkcję).
źródło
Co powiesz na napisanie funkcji takiej jak
.. i używaj go kiedy tylko potrzebujesz?
źródło
W przypadku pierwszego problemu, mam na myśli Pluralize, możesz użyć Inflectora .
Po drugie, możesz użyć rozszerzenia reprezentującego ciąg o nazwie takiej jak ToPronounString.
źródło
Dokładnie to samo pytanie zadał mi wczoraj członek naszego zespołu.
Odkąd pojawił się ponownie tutaj w StackOverflow, pomyślałem, że wszechświat mówi mi, żebym się zastanawiał nad stworzeniem przyzwoitego rozwiązania.
Szybko złożyłem coś w całość i wcale nie jest to idealne, ale może się przydać lub wywołać dyskusję / rozwój.
Ten kod opiera się na założeniu, że mogą istnieć 3 wiadomości. Jeden na zero pozycji, jeden na jeden przedmiot i jeden na więcej niż jeden przedmiot, które mają następującą strukturę:
singlePropertyName
singlePropertyName_Zero
singlePropertyName_Plural
Stworzyłem wewnętrzną klasę do testowania, aby naśladować klasę zasobów. Nie testowałem jeszcze tego przy użyciu rzeczywistego pliku zasobów, więc nie widzę jeszcze pełnego wyniku.
Oto kod (obecnie zawarłem kilka typów ogólnych, o których wiem, że mogłem określić trzeci parametr po prostu jako Typ, a także drugi parametr to ciąg znaków, myślę, że istnieje sposób na połączenie tych dwóch parametrów w coś lepszego, ale ja ' Wrócę do tego, kiedy będę miał wolną chwilę.
Testuj klasę zasobów:
i moja metoda szybkiego wykonywania
źródło
singlePropertyName_All
aby była jeszcze bardziej oczywista.Z mojego punktu widzenia Twoje pierwsze rozwiązanie jest najbardziej odpowiednie. Dlaczego tak mówię, jeśli potrzebujesz aplikacji do obsługi wielu języków, druga opcja może być żmudna. Przy pierwszym podejściu łatwo jest zlokalizować tekst bez większego wysiłku.
źródło
Możesz skorzystać z bardziej ogólnej wiadomości, np. „Czy na pewno chcesz usunąć wybrane elementy”.
źródło
Zależę od tego, jaką miłą wiadomość chcesz mieć. Od najłatwiejszego do najtrudniejszego:
Napisz ponownie komunikat o błędzie, aby uniknąć liczby mnogiej. Nie tak przyjemne dla użytkownika, ale szybsze.
Użyj bardziej ogólnego języka, ale nadal podawaj numery.
Użyj "pluralizacji" i systemu inflector ala Rails, żebyś mógł powiedzieć
pluralize(5,'bunch')
i dostać5 bunches
. Rails ma na to dobry wzór.W przypadku internacjonalizacji należy sprawdzić, co zapewnia Java. Będzie to obsługiwać szeroką gamę języków, w tym te, które mają różne formy przymiotników z 2 lub 3 elementami. Rozwiązanie „s” jest bardzo angielskie.
Wybór opcji zależy od Twoich celów produktowych. - ndp
źródło
Dlaczego miałbyś prezentować wiadomość, którą użytkownicy naprawdę zrozumieją? Jest to sprzeczne z 40-letnią historią programowania. Nooooo, dzieje się dobrze, nie psuj tego zrozumiałymi wiadomościami.
(j / k)
źródło
Zrób to tak, jak w World of Warcraft:
źródło
Trochę się skraca z
źródło
Jednym z podejść, o którym nie wspomniałem, byłoby użycie tagu substitution / select (np. Coś w rodzaju „Masz zamiar zgnieść {0} [? I ({0} = 1): / cactus / cacti /]”. (innymi słowy, użyj wyrażenia podobnego do formatu określającego podstawienie na podstawie tego, czy argument zero, traktowany jako liczba całkowita, jest równy 1). Widziałem takie tagi używane w dniach poprzedzających .net; nie znam żadnych standard dla nich w .net, ani nie znam najlepszego sposobu ich formatowania.
źródło
Pomyślałbym przez chwilę po wyjęciu z pudełka, wszystkie sugestie tutaj dotyczą albo wykonania liczby mnogiej (i martwienia się o więcej niż 1 poziom liczby mnogiej, płeć itp.) Lub w ogóle go nie używają i zapewniają przyjemne cofnięcie.
Pójdę drogą niejęzykową i użyję do tego wizualnych kolejek. np. wyobraź sobie aplikację Iphone, którą wybierasz, wycierając palcem. przed ich usunięciem za pomocą głównego przycisku usuwania, "potrząśnie" wybranymi elementami i wyświetli pole zatytułowane ze znakiem zapytania z przyciskami V (ok) lub X (anuluj) ...
Lub w świecie 3D Kinekt / Move / Wii - wyobraź sobie, że wybierasz pliki, przesuwasz dłonią do przycisku usuwania i każesz przesunąć dłonią nad głową w celu potwierdzenia (używając tych samych symboli wizualnych, jak wspomniałem wcześniej. Np. Zamiast tego z prośbą o usunięcie 3 plików? pokaże 3 pliki z najechanym półprzezroczystym czerwonym znakiem X i poleci zrobić coś, aby potwierdzić.
źródło