Bagaimana cara mengurangi switch dalam pernyataan switch?

9

Jadi saya membuat metode untuk membuat garis salam berdasarkan dua orang dari database.

Ada empat parameter: dua nama ( name1dan name2) dan dua jenis kelamin ( genderdan gender2).

Untuk setiap kombinasi gender, saya memiliki jenis output yang berbeda.

Misalnya: jika jenis kelamin 1 adalah M(laki-laki) dan jenis kelamin 2 juga M, hasilnya harus seperti:

Dear Sir name1 and Sir name2,

Saat ini, saklar saya terlihat seperti ini:

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

Perhatikan bahwa saya memiliki beberapa pilihan gender, seperti 'R'untuk "Dear Relation"dan beberapa lagi yang saya tidak punya waktu untuk menerjemahkan.

Bagaimana saya bisa mengurangi pernyataan saklar ganda ini?

Menempatkan saklar kedua dalam metode bukanlah pilihan karena ada juga kasus di mana kedua nama adalah sama dan kemudian output harus digabungkan seperti: "Dear Sir and Madame name1,"

moffeltje
sumber
1
Jika bahasa Anda memungkinkan, aktifkan ekspresi yang bervariasi dengan kedua nilai, mis gender1+gender2.
Kilian Foth
3
Pada titik yang tidak terkait, judul wanita untuk digunakan di sini adalah Madamtidak Madame. Madameadalah bentuk Prancis.
rojomoke
3
Agak tidak perlu, tetapi fakta bahwa variabel 'jenis kelamin' Anda bisa 'laki-laki', 'perempuan' atau 'hubungan' agak mengganggu ...
Paddy
4
"Perhatikan bahwa saya memiliki beberapa pilihan gender" Ya, itu memang sedang populer saat ini ...
Lightness Races in Orbit

Jawaban:

32

Tambahkan judul ke parameter printf:

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

Anda dapat mengekstrak sakelar ke fungsinya sendiri untuk kegunaan ulang dan kekompakan.

aneh ratchet
sumber
1
Itu kadang berhasil, kadang tidak ...
Deduplicator
4
@Dupuplikator Lakukan itu secara default dan menangani kasus luar biasa secara terpisah.
Val
17
… Dan jadikan fungsi itu genderToTitlesehingga Anda tidak perlu mengulanginya? (Atau gunakan loop)
Bergi
18

Solusi radikal: Biarkan pengguna menentukan judul mereka sendiri (dari daftar yang telah Anda tentukan sebelumnya).

Solusi Anda (sebagaimana dilihat melalui mata bahasa Inggris) hanya muncul untuk melayani Lords ("Sir") dan wanita; kebanyakan pria akan dipanggil sebagai "Tuan", sebagian besar perempuan sebagai "Nona", "Nyonya" atau "Nyonya", tergantung pada status perkawinan dan pendapat pribadi mereka. Lalu ada banyak penghargaan lainnya berdasarkan pada kedudukan profesional - "Dokter", "Profesor", "Pendeta" dan bahkan, jika Anda merasa benar-benar optimis tentang situs Anda, "Kekudusan"!

Solusi yang lebih sederhana: Anda memerlukan fungsi [tunggal] untuk menerjemahkan "jenis kelamin" menjadi bahasa kehormatan. Kode satu kali dan panggil untuk kedua orang:

printf("Dear %s %s and %s %s" 
   , getTitle( gender1 ), name1 
   , getTitle( gender2 ), name2 
   ) ; 
Phill W.
sumber
Masalahnya di sini adalah: Saya tidak memiliki kendali atas database sama sekali. tapi terima kasih atas informasi tambahan Anda, hargai itu :)
moffeltje
8
Dear Sirsebagai bentuk alamat sangat dapat diterima untuk semua pria. Saya setuju bahwa sebagai gelar , Sir (seperti dalam Sir Phill) harus dibatasi untuk ksatria (bukan bangsawan), tapi itu masalah yang berbeda.
rojomoke
1
Saya tidak melihat bagaimana ini membutuhkan akses ke database. Bagi saya, ini adalah metode terbersih untuk melakukan ini. Ada pengurangan switch bagus lainnya, tetapi ini adalah penggantian terbersih, serta memodulasi logika dengan baik.
Dan
4
@rojomoke Tidak, itu bukan masalah yang berbeda. Pertanyaan ini tentang "Dear Sir (masukkan nama di sini)", bukan tentang "Dear Sir". "Dear Sir (nama insert di sini)" yang menggunakan "Sir" sebagai judul.
hvd
Halaman pendaftaran frequent flyer BA, mungkin sekitar tahun 2003, memiliki "kekudusannya" dalam daftar drop-down judul. Masih berlaku untuk semua yang saya tahu. Saya ingat karena drop-down sangat lama sehingga crash browser portabel kami mengintegrasikan. Saya akan merekomendasikan bidang gratis, kecuali bahwa BA secara khusus mungkin berkonsultasi dengan Debrett dan mengetahui beberapa bentuk setiap judul untuk konteks yang berbeda (alamat amplop dan salam minimum sebagai minimum)
Steve Jessop
9

Judul benar-benar termasuk dalam database, tetapi Anda menyatakan tidak memiliki kendali atas ini. Anda belum menentukan tag bahasa tetapi sintaksnya ada dalam keluarga C, jadi ini akan menjadi pseudocode yang hampir C ++:

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

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

Manfaatnya adalah Anda mengubur logika pemilihan dalam struktur data daripada struktur kode: ini mirip dengan mendelegasikan ke database, dan lebih fleksibel. Jika Anda menyimpan peta itu sebagai konstanta statis di suatu tempat, Anda hampir dapat menggunakannya seperti database: menjadi sebuah struktur tunggal untuk memperbarui yang dapat digunakan di banyak tempat dalam kode tanpa perlu menulis lebih banyak kode.


sumber
Ini mungkin ide yang baik untuk pergi dengan C ++ 11 initializer sintaks, dan membuatnya static const: static const map<string, string> titles{make_pair("M", "Sir"), make_pair("F", "Madam")};. Yah, seseorang dapat meninggalkannya constjika memodifikasi itu harus diizinkan.
Deduplicator
@Dupuplikator pasti, ada cara yang lebih baik. Saya pergi untuk kesederhanaan di sini mengingat tidak ada tag bahasa tetapi sepertinya C ++. Tapi Anda benar, dengan asumsi C ++ 11.
3

Jawaban ratchet freak adalah ide yang cukup bagus jika kalimatnya semua pola yang sama, tetapi dengan dua insets, masing-masing hanya bergantung pada gender1masing-masing gender2.

Jawaban Phil W. mungkin jawaban yang paling fleksibel karena memungkinkan kontrol eksplisit atas salam, meskipun dia cukup benar itu adalah perubahan radikal. Anda mungkin tidak memiliki data dalam formulir itu.

Jawaban Kilian Foth mungkin adalah yang terbaik untuk pertanyaan yang diajukan, meskipun ia bergantung pada pengalihan string, yang mungkin tidak mungkin atau setidaknya paling mahal.

Penyempurnaan pada jawaban Kilian adalah menghitung nilai tunggal dari kedua input, dan mengaktifkannya:

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

Tentu saja, karena Anda mendapatkan keempat input (2 nama dan 2 gender) dari database, menambahkan tabel lain dan bergabung untuk mendapatkan salam yang tepat mungkin lebih fleksibel dan mungkin lebih mudah daripada yang di atas.

Deduplicator
sumber
2

Jika bahasa Anda memungkinkan Anda melakukannya, Anda dapat menulis

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

Ini tidak selalu lebih baik daripada versi Anda, karena masih ada duplikasi, tetapi itu menghindari bersarang switch.

Kilian Foth
sumber
5
Jika Anda melakukan ini, karena cinta cupcakes, letakkan ini dalam array atau sesuatu dan singkirkan saklarnya… salam ['MM'] = "Tuan-tuan yang terhormat"; salam ['MF'] = "Nyonya dan Tuan yang terhormat"; diinginkanSalutation = salam [gender1 + gender2];
JDT
1
Kamus @JDT ?
nyamuk
Apa yang harus dipanggil yang sebenarnya tergantung pada bahasa, tetapi pada dasarnya kumpulan kunci dan nilai, ya.
JDT
1
Ada sedikit penyempurnaan untuk itu, yang bekerja di hampir semua bahasa: Hitung bilangan bulat tunggal dari kedua karakter input, dan aktifkan itu, bukan pada string.
Deduplicator
0

Anda biasanya ingin string UI seperti ini ditarik dari tabel string alih-alih dikode dalam kode sumber, untuk pelokalan dan kemudahan memperbarui. Jadi pendekatan yang akan saya lakukan adalah menggunakan input untuk membangun kunci pencarian, jadi sesuatu seperti:

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

Saran lain tentang membiarkan pengguna memilih judul mereka sendiri adalah valid, jika Anda memiliki kesempatan untuk mendapatkan informasi itu. Saya masih akan menggunakan tabel string lookup dalam solusinya.

bmm6o
sumber