Bir switch deyimindeki bir switch nasıl azaltılır?


9

Bu yüzden bir veritabanından iki kişiye dayalı bir selamlama hattı oluşturmak için bir yöntem yapıyorum.

Dört parametre vardır: iki isim ( name1ve name2) ve iki cinsiyet ( genderve gender2).

Her cinsiyet kombinasyonu için bir çeşit farklı ürünüm var.

Örneğin: cinsiyet 1 M(erkek) ve cinsiyet 2 de Mise, çıktı şöyle olmalıdır:

Dear Sir name1 and Sir name2,

Şu anda, anahtarım şöyle görünüyor:

switch(gender1){
    case 'M':
        switch(gender2){
            case 'M': printf("Dear Sir %s and Sir %s", name1, name2); break;
            case 'W': printf("Dear Sir %s and Madame %s", name1, name2); break;
            case 'R': ...
        }
        break;
    case 'W':
        switch(gender2){
            case 'M': printf("Dear Madame %s and Sir %s", name1, name2); break
            case 'W': printf("Dear Madame %s and Madame %s", name1, name2); break;
            case 'R': ...
        }
        break;
    case ...etc.
}

Ben gibi, birden fazla cinsiyet seçenek var o Not 'R'için "Dear Relation"biraz daha ben çevirmek için zamanım yok olduğunu ve.

Bu çift anahtar ifadesini nasıl azaltabilirim?

İkinci anahtarı bir yönteme koymak bir seçenek değildir, çünkü her iki adın da aynı olduğu ve çıktının aşağıdaki gibi birleştirilmesi gereken bir durum da vardır: "Dear Sir and Madame name1,"



1
Diliniz buna izin veriyorsa, her iki değerle de değişen bir ifadeyi açın , örn gender1+gender2.
Kilian Foth

3
İlgisiz bir noktada, burada kullanılacak kadın başlığı Madamdeğil Madame. MadameFransız biçimidir.
rojomoke

3
Biraz gereksiz, ama 'cinsiyet' değişkeninizin 'erkek', 'kadın' veya 'ilişki' olabileceği gerçeği biraz rahatsız edici ...
Paddy

4
"Birden fazla cinsiyet seçeneğimin olduğunu unutmayın" Pekala, bu günlerde kesinlikle moda oldu ...
Orbit'teki Hafiflik Yarışları

Yanıtlar:


32

Başlığı printf parametrelerine ekleyin:

char* title1;
switch(gender1){
    case 'M':
        title1 = "Sir";
        break;
    case 'W':
       title1 = "Madam";
        break;
    case ...etc.
}
char* title2;
switch(gender2){
    case 'M':
        title2 = "Sir";
        break;
    case 'W':
       title2 = "Madam";
        break;
    case ...etc.
}
printf("Dear %s %s and %s %s", title1, name1, title2, name2);

yeniden kullanılabilirlik ve kompaktlık için düğmeyi kendi işlevine çıkarabilirsiniz.


1
Bazen işe
yarar

4
@Deduplicator Bunu varsayılan olarak yapın ve istisnai durumları ayrı ayrı ele alın.
Val

17
… Ve genderToTitletekrar etmenize gerek kalmayacak şekilde bir işlev yapsın mı? (Veya bir döngü kullanın)
Bergi

18

Radikal çözüm: Kullanıcının kendi başlığını belirtmesine izin verin (sağladığınız önceden tanımlanmış bir listeden).

Çözümünüz (İngilizce gözlerle görüldüğü gibi) sadece Lordlar ("Efendim") ve bayanlar için uygun görünüyor; çoğu erkek medeni durumlarına ve kişisel görüşlerine bağlı olarak çoğu kadın ya "Bayan", "Bayan" ya da "Bayan" olarak adlandırılır. Sonra "Doktorlar", "Profesörler", "Saygılar" ve hatta, siteniz hakkında gerçekten iyimser hissediyorsanız , "Holiness" profesyonel sıralamalar dayalı bir sürü onur vardır !

Daha basit çözüm: "Cinsiyeti" onurlu bir dile çevirmek için [tek] bir işleve ihtiyacınız var. Bir kez kodlayın ve her iki kişi için arayın:

printf("Dear %s %s and %s %s" 
   , getTitle( gender1 ), name1 
   , getTitle( gender2 ), name2 
   ) ; 

Sorun burada: Ben veritabanı üzerinde herhangi bir denetimim yok. ama ek bilgi için teşekkürler, takdir :)
moffeltje

8
Dear Sirbir adres biçimi olarak tüm erkekler için mükemmel kabul edilebilir. Bir unvan olarak , Efendim (olduğu gibi Sir Phill) şövalyelerle (lordlarla değil) sınırlandırılması gerektiğini kabul ediyorum , ancak bu farklı bir konudur.
rojomoke

1
Bunun veritabanına nasıl erişim gerektirdiğini göremiyorum. Bu benim için bunu yapmanın en temiz yöntemidir. Başka güzel anahtar indirimleri var, ancak bu en temiz değiştirme ve mantığı güzel bir şekilde değiştiriyor.
Dan

4
@rojomoke Hayır, bu farklı bir mesele değil. Bu soru düz bir "Sevgili Efendim" hakkında değil, "Sevgili Efendim (buraya isim girin)" ile ilgilidir. "Sayın (burada insert name)" olan bir başlık olarak "Sir" kullanarak.
Hvd

BA sık uçan broşür kayıt sayfası, belki de 2003 dolaylarında, başlıkların açılan listesinde "kutsallığı" vardı. Hala bildiğim her şeyi yapıyor. Hatırlıyorum çünkü açılır menü o kadar uzun sürdü ki entegre ettiğimiz taşınabilir tarayıcıyı çökertti. Özellikle BA'nın muhtemelen Debrett's'e danışması ve farklı bağlamlar için her bir başlığın birden çok biçimini bilmesinin dışında, ücretsiz bir alan tavsiye ederim (farklı zarf adresi ve minimum olarak selamlama)
Steve Jessop

9

Başlıklar gerçekten veritabanına ait, ancak bunun üzerinde kontrolünüz olmadığını söylediniz. Bir dil etiketi belirtmediniz ancak sözdizimi C ailesinde, bu yüzden bu neredeyse C ++ olan sözde kod olacak:

map<string, string> titles;
titles.emplace("M", "Sir");
titles.emplace("F", "Madam");

cout << "Dear " << titles[gender1] << " " << name1 << " and "
     << titles[gender2] << " " << name2 << endl;

Bunun yararı, seçim mantığını bir kod yapısından ziyade bir veri yapısına gömmenizdir: bu, veritabanına yetki vermeye benzer ve daha esnektir. Bu haritayı bir yerde statik bir sabit olarak tutarsanız, neredeyse bir veritabanı gibi kullanabilirsiniz: daha fazla kod yazmanıza gerek kalmadan kodun birçok yerinde kullanılabilecek tek bir yapı haline gelir .



C ++ sözdizimi başlatıcısı 11 ile gitmek iyi bir fikir olabilir ve bunun yapımı olabilir static const: static const map<string, string> titles{make_pair("M", "Sir"), make_pair("F", "Madam")};. Peki, constdeğiştirilmesine izin verilmesi gerekiyorsa dışarıda bırakılabilir.
Deduplicator

@Deduplicator kesinlikle daha iyi bir yol var. Burada dil etiketi yok ama C ++ gibi görünüyor basitlik için gidiyordu . Ama haklısın, C ++ 11 olduğunu varsayalım.

3

cırcırta ucube'nin cevabı , cümlelerin hepsi aynı kalıpsa, ancak her biri sadece gender1ilgili olana bağlı iki girişle oldukça iyi bir fikirdir gender2.

Phil W.'nin cevabı muhtemelen en esnek cevaptır, çünkü selamlama üzerinde açık kontrole izin verir, ancak bu oldukça radikal bir değişikliktir. Veriler bu formda olmayabilir.

Kilian Foth'un cevabı muhtemelen sorulduğu gibi soru için en iyisidir, ancak mümkün olmayan veya en azından daha pahalı olan bir ipi açmaya bağlıdır.

Kilian'ın cevabındaki bir ayrıntılandırma, her iki girişten de tek bir değer hesaplamak ve bunu açmaktır:

// Using a macro in C for readability. C++ would use a constexpr function
#define COMBINE(a, b) ((a<<CHAR_BIT)+b)

switch( COMBINE(gender1, gender2)) {
  case COMBINE('M', 'M'): 
    print "Dear Sirs";
    break;
  case COMBINE('M', 'F'): 
  case COMBINE('F', 'M'): 
    print "Dear Sir and Madam";
    break;
  ...
#undef COMBINE

Tabii ki, bir veritabanından dört girişi (2 isim ve 2 cinsiyet) alırken, uygun bir selamlama elde etmek için başka bir tablo ekleyerek ve buna katılmak muhtemelen daha esnek ve belki de yukarıdakilerden daha kolaydır.


2

Eğer diliniz bunu yapmanıza izin veriyorsa,

switch(gender1+gender2) {
  case "MM": 
    print "Dear Sirs";
    break;
  case "MF": 
  case "FM":
    print "Dear Sir and Madam";
    break;
  ...

Yine de çoğaltma olduğundan, sürümünüzden daha iyi olması gerekmez, ancak iç içe geçmişleri önler switch.


5
Bunu yaparsanız, cupcakes sevgisi için bunu bir dizi ya da bir şey koymak ve anahtarı kurtulmak .... salutation ['MM'] = "Sayın Baylar"; selamlama ['MF'] = "Sayın Bayan ve Efendim"; wantedSalutation = selamlama [cinsiyet1 + cinsiyet2];
JDT

1
@JDT sözlüğü mü?
gnat

Buna tam olarak dile bağlı, ancak temelde bir anahtar ve değer koleksiyonu var, evet.
JDT

1
Hemen hemen her dilde çalışan küçük bir ayrıntılandırma vardır: Her iki giriş karakterinden tek bir tam sayı hesaplayın ve bunu bir dizede değil açın.
Deduplicator

0

Yerelleştirme ve güncelleme kolaylığı için genellikle bunun gibi kullanıcı arabirimi dizelerinin kaynak kodda sabit kodlanmak yerine bir dize tablosundan alınmasını istersiniz. Yani benim yaklaşım yaklaşımı bir arama anahtarı oluşturmak için girişleri kullanmak olacaktır, böylece şöyle bir şey:

var lookupKey = "SALUTATION_" + gender1 + "_" + gender2;
var format = GetLocalizedString(lookupKey);
printf(format, name1, name2);

Bu bilgileri alma şansınız varsa, kullanıcıların kendi başlıklarını seçmelerine izin verme hakkındaki diğer öneriler geçerlidir. Hala çözümde bir dize tablo arama kullanırdım.

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.