将多个布尔值(来自HTML表单)转换为字符串(Go语言)

huangapple go评论123阅读模式
英文:

Turn multiple bool values (from HTML form) into a string (Go)

问题

我知道标题很糟糕,但不确定如何提出这个问题...我有一个带有选择输入的HTML表单,可以返回多个值,例如:

  1. <select name="rights" multiple>
  2. <option value="create">create</option>
  3. <option value="view">view</option>
  4. <option value="edit">edit</option>
  5. <option value="delete">delete</option>
  6. </select>

然后我有一个函数可以检查表单包含哪些值:

  1. func formContains(slice []string, item string) bool {
  2. set := make(map[string]struct{}, len(slice))
  3. for _, s := range slice {
  4. set
    展开收缩
    = struct{}{}
  5. }
  6. _, ok := set[item]
  7. return ok
  8. }

所以我可以调用:

  1. err := r.ParseForm()
  2. // 错误检查
  3. rights := r.Form["rights"]
  4. log.Println(formContains(rights, "create"))

我想做的是检查表单包含哪些值,然后返回一个字符串,例如,如果表单包含权限"create"和"delete",则应返回:"1001",如果包含权限"view"、"edit"和"delete",则应返回"0111"。

我可以通过大量的if/else或switch语句来实现期望的结果,但我知道一定有更聪明的方法...我考虑过创建一个数组,最终看起来像这样:[0] 1 [0] 1(如果权限是"view"和"delete"),然后将数组转换为字符串...但到目前为止还没有成功...

英文:

I know the title is really bad, but not sure how to ask this question.. I have a HTML form with a select input returning multiple values, e.g.:

  1. &lt;select name=&quot;rights&quot; multiple&gt;
  2. &lt;option value=&quot;create&quot;&gt;create&lt;/option&gt;
  3. &lt;option value=&quot;view&quot;&gt;view&lt;/option&gt;
  4. &lt;option value=&quot;edit&quot;&gt;edit&lt;/option&gt;
  5. &lt;option value=&quot;delete&quot;&gt;delete&lt;/option&gt;
  6. &lt;/select&gt;

I then have a function that can check which values the form contains:

  1. func formContains(slice []string, item string) bool {
  2. set := make(map[string]struct{}, len(slice))
  3. for _, s := range slice {
  4. set
    展开收缩
    = struct{}{}
  5. }
  6. _, ok := set[item]
  7. return ok
  8. }

so I can call:

  1. err := r.ParseForm()
  2. // err check
  3. rights := r.Form[&quot;rights&quot;]
  4. log.Println(formContains(rights, &quot;create&quot;))

What I would like to do is to check which values the form contains, and then return a string, e.g., if the form contains the rights "create" and "delete" then it should return:
"1001", if it contains the rights "view", "edit" and "delete" then it should return "0111".

I would be able to achieve the desired result with a lot of if/else or switch statements, but I know there must be a smarter way.. I considered the possibility of creating an array that would end up looking like this: [0] 1 [0] 1 (in case the rights were "view" and "delete"), and then convert the array to a string.. but so far it's been unsuccessful..

答案1

得分: 4

我认为你应该研究一下位运算的主题。没有必要保留一个数组,你的四个操作可以用整数来表示:

  1. create = 1(二进制表示为0001
  2. view = 2(二进制表示为0010
  3. edit = 4(二进制表示为0100
  4. delete = 8(二进制表示为1000

为了获取所有选定的权限,你可以使用"位或"运算符:

  1. rights := 0
  2. rights |= 2
  3. rights |= 4
  4. // 现在rights的值为6,即view和edit

然后,当你需要检查特定权限是否已启用时,可以使用"位与"运算符:

  1. func hasPermission(rights int, item int) bool {
  2. return (rights & item) == item
  3. }

请参考我的完整示例:https://play.golang.org/p/UPZkqsrDS4

  1. package main
  2. import (
  3. "fmt"
  4. )
  5. func main() {
  6. create := 1
  7. view := 2
  8. edit := 4
  9. delete := 8
  10. rights := 0
  11. rights |= view
  12. rights |= edit
  13. fmt.Println(hasPermission(rights , create))
  14. fmt.Println(hasPermission(rights , view))
  15. fmt.Println(hasPermission(rights , edit))
  16. fmt.Println(hasPermission(rights , delete))
  17. }
  18. func hasPermission(rights int, item int) bool {
  19. return (rights & item) == item
  20. }
英文:

I think you should look into the bitwise operations topic. There is no need to keep an array, your four operations can be represented as integers instead:

  1. create = 1 (0001 in binary representation)
  2. view = 2 (0010 in binary representation)
  3. edit = 4 (0100 in binary representation)
  4. delete = 8 (1000 in binary representation)

In order get all selected rights you can use bitwise OR operation:

  1. rights := 0
  2. rights |= 2
  3. rights |= 4
  4. // rights is 6 now, i.e. view and edit

Then when you need to check if specific right is enabled, you can use bitwise AND opration:

  1. func hasPermission(rights int, item int) bool {
  2. return (rights &amp; item) == item
  3. }

See my complete example: https://play.golang.org/p/UPZkqsrDS4

  1. package main
  2. import (
  3. &quot;fmt&quot;
  4. )
  5. func main() {
  6. create := 1
  7. view := 2
  8. edit := 4
  9. delete := 8
  10. rights := 0
  11. rights |= view
  12. rights |= edit
  13. fmt.Println(hasPermission(rights , create))
  14. fmt.Println(hasPermission(rights , view))
  15. fmt.Println(hasPermission(rights , edit))
  16. fmt.Println(hasPermission(rights , delete))
  17. }
  18. func hasPermission(rights int, item int) bool {
  19. return (rights &amp; item) == item
  20. }

答案2

得分: 2

也许可以这样写:

  1. keys := []string{"create", "view", "edit", "delete"}
  2. b := 0
  3. for idx, key := range keys {
  4. if len(r.Form[key]) != 0 {
  5. b += 1 << uint(idx)
  6. }
  7. }
  8. s := fmt.Sprintf("%04b", b)

使用s := fmt.Sprintf("%04b", b)将"二进制权限字符串"存储到一个字符串变量中。

英文:

Perhaps something like

  1. keys := []string{&quot;create&quot;, &quot;view&quot;, &quot;edit&quot;, &quot;delete&quot;}
  2. b := 0
  3. for idx, key := range keys {
  4. if len(r.Form[key]) != 0 {
  5. b += 1 &lt;&lt; uint(idx)
  6. }
  7. }
  8. fmt.Printf(&quot;%04b&quot;, b)

use s := fmt.Sprintf(&quot;%04b&quot;, b) to store the "binari rights string" into an string variable.

huangapple
  • 本文由 发表于 2017年4月5日 23:12:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/43235199.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定