douan8473 2016-03-14 20:51 采纳率: 100%
浏览 74
已采纳

在Go中解析简单的复选框组

I'm parsing a form in Go and I frequently find groups of checkboxes which need to be processed into text like so:

[ ] Foo
[x] Bar
[ ] Baz
[x] Bat

where the output should be a comma-separated list "BarText, BatText" corresponding to the checked items, or "None" if none of the items are checked. What is a good way to handle this situation? Repeating the logic each time seems like a bad idea.

In the spirit of YAGNI there's no need to handle possible future changes like translations into other languages (actually this example is highly unlikely to be useful in the present context).

Efficiency is unimportant for this application.

Edit: code looks like this (source):

func handleCheckboxesForm(w http.ResponseWriter, r *http.Request) {
    b := func(name string) string { // helper function for boolean values in the form
        return r.FormValue(name) == "on"
    }

    text := "Header stuff here"

    mytext := ""
    if b("nfpa-alk") {
        mytext += ", alkaline"
    }
    if b("nfpa-acid") {
        mytext += ", acid"
    }
    if b("nfpa-w") {
        mytext += ", reacts violently with water"
    }
    if b("nfpa-alk") || b("nfpa-acid") || b("nfpa-w") {
        text += mytext[2:] + "
"
    } else {
        text += "none
"
    }

    // lots of other checkbox groups here

    // do stuff with text
}
  • 写回答

2条回答 默认 最新

  • dtvfshi5248 2016-03-14 21:31
    关注

    There are many repeating code in yours which can be optimized out.

    Your code must contain at least the following "fragments":

    1. The mappings from entry name to entry text, which can be stored in a map, e.g.

      var mappings = map[string]string {
          "Foo": "Foo text",
          "Bar": "Bar text",
          "Baz": "Baz text",
          "Bat": "Bat text",
          // ... other mappings
      }
      
    2. And the list of keys belonging to a group, which can be stored in a slice, e.g.

      var group1 = []string{"Foo", "Bar", "Baz", "Bat"}
      

    Once you defined these, you can have a helper method which handles a group:

    func handleGroup(r *http.Request, group []string) (res string) {
        for _, v := range group {
            if r.FormValue(v) == "on" {
                res := ", " + mappings[v]
            }
        }
        if res == "" {
            return "none
    "
        }
        return res[2:] + "
    "
    }
    

    That's all. After this your handler can be this simple:

    func checkboxHandler(w http.ResponseWriter, r *http.Request) {
        // Handle group1:
        res1 := handleGroup(r, group1)
    
        // Handle group2:
        res2 := handleGroup(r, group2)
    }
    

    Notes:

    It wasn't your requirement, but this solution handles translations very easily: each translation can have its own mappings map, and that's all. Nothing else needs to be changed.

    Performance also wasn't your concern, but appending strings isn't very efficient this way. If performance is at least a little concern, you can improve it without adding complexity by utilizing bytes.Buffer:

    func handleGroup(r *http.Request, group []string) string {
        buf := &bytes.Buffer{}
        for _, v := range group {
            if r.FormValue(v) == "on" {
                buf.WriteString(", ")
                buf.WriteString(mappings[v])
            }
        }
        if buf.Len() == 0 {
            return "none
    "
        }
        buf.WriteString("
    ")
        return string(buf.Bytes()[2:])
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥25 关于##爬虫##的问题,如何解决?:
  • ¥15 ZABBIX6.0L连接数据库报错,如何解决?(操作系统-centos)
  • ¥15 找一位技术过硬的游戏pj程序员
  • ¥15 matlab生成电测深三层曲线模型代码
  • ¥50 随机森林与房贷信用风险模型
  • ¥50 buildozer打包kivy app失败
  • ¥30 在vs2022里运行python代码
  • ¥15 不同尺寸货物如何寻找合适的包装箱型谱
  • ¥15 求解 yolo算法问题
  • ¥15 虚拟机打包apk出现错误