Làm thế nào để giảm một chuyển đổi trong một tuyên bố chuyển đổi?


9

Vì vậy, tôi đang thực hiện một phương pháp để tạo ra một dòng chào dựa trên hai người từ cơ sở dữ liệu.

Có bốn tham số: hai tên ( name1name2) và hai giới tính ( gendergender2).

Đối với mỗi kết hợp giới tính, tôi có một loại đầu ra khác nhau.

Ví dụ: nếu giới tính 1 là M(nam giới) và giới tính 2 cũng vậy M, thì đầu ra phải giống như:

Dear Sir name1 and Sir name2,

Tại thời điểm này, công tắc của tôi trông như thế này:

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

Lưu ý rằng tôi có nhiều tùy chọn giới tính, như 'R'cho "Dear Relation"và một số tùy chọn khác mà tôi không có thời gian để dịch.

Làm thế nào tôi có thể giảm tuyên bố chuyển đổi kép này?

Đặt công tắc thứ hai trong một phương thức không phải là một tùy chọn vì cũng có trường hợp cả hai tên giống nhau và sau đó đầu ra phải được kết hợp như sau: "Dear Sir and Madame name1,"



1
Nếu ngôn ngữ của bạn cho phép nó, bật một biểu thức thay đổi theo cả hai giá trị, ví dụ gender1+gender2.
Kilian Foth 14/07/2015

3
Trên một điểm không liên quan, tiêu đề nữ để sử dụng ở đây là Madam, không Madame. Madamelà hình thức của Pháp.
rojomoke 14/07/2015

3
Hơi không cần thiết, nhưng thực tế là biến 'giới tính' của bạn có thể là 'nam', 'nữ' hoặc 'quan hệ' là một chút đáng lo ngại ...
Paddy

4
"Lưu ý rằng tôi có nhiều lựa chọn giới tính" Chà, điều đó chắc chắn đang thịnh hành những ngày này ...
Các cuộc đua Lightness trong quỹ đạo

Câu trả lời:


32

Thêm tiêu đề cho các tham số của 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);

bạn có thể trích xuất công tắc sang chức năng của chính nó để tái sử dụng và gọn nhẹ.


1
Điều đó đôi khi hoạt động, đôi khi không ...
Ded repeatator

4
@Ded repeatator Làm điều đó theo mặc định và xử lý các trường hợp đặc biệt riêng biệt.
Val

17
Có thể làm cho nó một chức năng genderToTitleđể bạn không phải lặp lại nó? (Hoặc sử dụng vòng lặp)
Bergi 14/07/2015

18

Giải pháp cấp tiến: Cho phép người dùng chỉ định tiêu đề của riêng họ (từ danh sách được xác định trước mà bạn cung cấp).

Giải pháp của bạn (như được nhìn qua đôi mắt tiếng Anh) chỉ xuất hiện để phục vụ cho Lãnh chúa ("Ngài") và phụ nữ; hầu hết đàn ông sẽ được gọi là "Mr", hầu hết phụ nữ là "hoa hậu", "bà" hoặc "bà", tùy thuộc vào tình trạng hôn nhân và ý kiến ​​cá nhân của họ. Sau đó, có một loạt các danh dự khác dựa trên bảng xếp hạng chuyên nghiệp - "Bác sĩ", "Giáo sư", "Tôn kính" và thậm chí, nếu bạn cảm thấy thực sự lạc quan về trang web của mình, "Sự thánh thiện"!

Giải pháp đơn giản hơn: Bạn cần một hàm [đơn] để dịch "giới tính" thành một kính ngữ. Mã nó một lần và gọi nó cho cả hai người:

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

Vấn đề ở đây là: Tôi không có bất kỳ quyền kiểm soát nào đối với cơ sở dữ liệu. nhưng cảm ơn vì thông tin bổ sung của bạn, đánh giá cao nó :)
moffeltje

8
Dear Sirnhư một hình thức địa chỉ là hoàn toàn chấp nhận được đối với tất cả nam giới. Tôi đồng ý rằng với tư cách là một tiêu đề , Sir (như trong Sir Phill) nên được giới hạn trong các hiệp sĩ (không phải lãnh chúa), nhưng đó là một vấn đề khác.
rojomoke 14/07/2015

1
Tôi không thấy làm thế nào điều này sẽ yêu cầu quyền truy cập vào cơ sở dữ liệu. Điều này, với tôi, là phương pháp sạch nhất để làm điều này. Có những cách giảm chuyển đổi tốt đẹp khác, nhưng đây là sự thay thế sạch nhất, cũng như điều chỉnh logic.
Dan

4
@rojomoke Không, đó không phải là vấn đề khác. Câu hỏi này là về "Dear Sir (điền tên vào đây)", không phải về một "Dear Sir" đơn giản. "Dear Sir (điền tên vào đây)" đang sử dụng "Sir" làm tiêu đề.
hvd

Trang đăng ký khách hàng thường xuyên của BA, có thể vào khoảng năm 2003, có "sự thánh thiện" của anh ấy trong danh sách thả xuống của các tiêu đề. Vẫn làm cho tất cả những gì tôi biết. Tôi nhớ vì trình đơn thả xuống quá lâu nên nó đã làm sập trình duyệt di động mà chúng tôi đang tích hợp. Tôi muốn giới thiệu một trường miễn phí, ngoại trừ BA đặc biệt có thể hỏi ý kiến ​​của Debrett và biết nhiều hình thức của mỗi tiêu đề cho các bối cảnh khác nhau (địa chỉ phong bì khác nhau và lời chào tối thiểu)
Steve Jessop

9

Các tiêu đề thực sự thuộc về cơ sở dữ liệu, nhưng bạn nói rằng bạn không kiểm soát được điều này. Bạn chưa chỉ định thẻ ngôn ngữ nhưng cú pháp thuộc họ C, vì vậy đây sẽ là mã giả gần như C ++:

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

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

Lợi ích của việc này là bạn chôn logic lựa chọn trong cấu trúc dữ liệu thay vì cấu trúc mã: điều này tương tự như ủy thác cho cơ sở dữ liệu và linh hoạt hơn. Nếu bạn giữ bản đồ đó dưới dạng hằng số tĩnh ở đâu đó, bạn gần như có thể sử dụng nó như cơ sở dữ liệu: nó trở thành một cấu trúc duy nhất để cập nhật, có thể được sử dụng ở nhiều nơi trong mã mà không cần phải viết thêm mã.



Nó có thể là một ý tưởng tốt để đi với cú pháp khởi tạo C ++ 11 và làm cho nó static const: static const map<string, string> titles{make_pair("M", "Sir"), make_pair("F", "Madam")};. Vâng, người ta có thể rời constkhỏi nếu sửa đổi nó nên được cho phép.
Ded repeatator

@Ded repeatator chắc chắn, có một cách tốt hơn. Tôi đã đi đơn giản ở đây vì không có thẻ ngôn ngữ nhưng có vẻ như C ++. Nhưng bạn đã đúng, giả sử C ++ 11.

3

câu trả lời ratchet quái của khá một ý tưởng tốt nếu các câu đều cùng một khuôn mẫu, nhưng với hai insets, mỗi chỉ phụ thuộc vào gender1tương ứng gender2.

Câu trả lời của Phil W. có lẽ là câu trả lời linh hoạt nhất vì nó cho phép kiểm soát rõ ràng lời chào, mặc dù anh ta hoàn toàn chính xác đó là một sự thay đổi triệt để. Bạn có thể không có dữ liệu ở dạng đó.

Câu trả lời của Kilian Foth có lẽ là câu hỏi hay nhất cho câu hỏi, mặc dù anh ta phụ thuộc vào việc chuyển sang một chuỗi, điều này có thể không thể hoặc ít nhất là đắt hơn.

Một sàng lọc cho câu trả lời của Kilian là tính toán một giá trị duy nhất từ ​​cả hai yếu tố đầu vào và chuyển sang đó:

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

Tất nhiên, khi bạn nhận được tất cả bốn đầu vào (2 tên và 2 giới tính) từ cơ sở dữ liệu, việc thêm một bảng khác và tham gia vào đó để có được lời chào phù hợp có lẽ linh hoạt hơn và có thể dễ dàng hơn so với ở trên.


2

Nếu ngôn ngữ của bạn cho phép bạn làm điều đó, bạn có thể viết

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

Nó không nhất thiết phải tốt hơn phiên bản của bạn, vì vẫn còn trùng lặp, nhưng nó tránh được lồng nhau switch.


5
Nếu bạn làm điều này, vì tình yêu của cupcakes hãy đặt nó vào một mảng hoặc thứ gì đó và thoát khỏi công tắc .... lời chào ['MM'] = "Dear Sirs"; lời chào ['MF'] = "Kính gửi ông và bà"; mong muốnSaluting = lời chào [male1 + male2];
JDT

1
@JDT từ điển ?
gnat

Gọi cái gì chính xác phụ thuộc vào ngôn ngữ, nhưng về cơ bản là một bộ sưu tập các khóa và giá trị, vâng.
JDT

1
Có một tinh chỉnh nhỏ cho điều đó, hoạt động ở bất kỳ ngôn ngữ nào: Tính một số nguyên duy nhất từ ​​cả hai ký tự đầu vào và bật nó, không phải trên một chuỗi.
Ded repeatator

0

Thông thường, bạn muốn các chuỗi UI như thế này được kéo vào từ bảng chuỗi thay vì được mã hóa cứng trong mã nguồn, để bản địa hóa và dễ cập nhật. Vì vậy, cách tiếp cận tôi sẽ sử dụng là sử dụng các yếu tố đầu vào để xây dựng khóa tra cứu, vì vậy đại loại như:

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

Các đề xuất khác về việc cho phép người dùng chọn tiêu đề của riêng họ là hợp lệ, nếu bạn có cơ hội nhận được thông tin đó. Tôi vẫn sẽ sử dụng một tra cứu bảng chuỗi trong giải pháp.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.