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

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

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

问题

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

<select name="rights" multiple>
  <option value="create">create</option>
  <option value="view">view</option>
  <option value="edit">edit</option>
  <option value="delete">delete</option>
</select>

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

func formContains(slice []string, item string) bool {
    set := make(map[string]struct{}, len(slice))
    for _, s := range slice {
        set
展开收缩
= struct{}{} } _, ok := set[item] return ok }

所以我可以调用:

err := r.ParseForm()
// 错误检查
rights := r.Form["rights"]
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.:

&lt;select name=&quot;rights&quot; multiple&gt;
  &lt;option value=&quot;create&quot;&gt;create&lt;/option&gt;
  &lt;option value=&quot;view&quot;&gt;view&lt;/option&gt;
  &lt;option value=&quot;edit&quot;&gt;edit&lt;/option&gt;
  &lt;option value=&quot;delete&quot;&gt;delete&lt;/option&gt;
&lt;/select&gt;

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

func formContains(slice []string, item string) bool {
    set := make(map[string]struct{}, len(slice))
    for _, s := range slice {
        set
展开收缩
= struct{}{} } _, ok := set[item] return ok }

so I can call:

err := r.ParseForm()
// err check
rights := r.Form[&quot;rights&quot;]
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

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

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

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

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

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

func hasPermission(rights int, item int) bool {
    return (rights & item) == item 
}

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

package main

import (
    "fmt"
)


func main() {
    create := 1
    view   := 2
    edit   := 4
    delete := 8
    
    rights := 0
    rights |= view
    rights |= edit


    fmt.Println(hasPermission(rights , create))
    fmt.Println(hasPermission(rights , view))
    fmt.Println(hasPermission(rights , edit))
    fmt.Println(hasPermission(rights , delete))
}


func hasPermission(rights int, item int) bool {
    return (rights & item) == item 
}
英文:

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:

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

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

rights := 0
rights |= 2
rights |= 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:

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

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

package main

import (
	&quot;fmt&quot;
)


func main() {
	create := 1
	view   := 2
	edit   := 4
	delete := 8
	
	rights := 0
	rights |= view
	rights |= edit


	fmt.Println(hasPermission(rights , create))
	fmt.Println(hasPermission(rights , view))
	fmt.Println(hasPermission(rights , edit))
	fmt.Println(hasPermission(rights , delete))
}


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

答案2

得分: 2

也许可以这样写:

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

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

英文:

Perhaps something like

keys := []string{&quot;create&quot;, &quot;view&quot;, &quot;edit&quot;, &quot;delete&quot;}
b := 0
for idx, key := range keys {
	if len(r.Form[key]) != 0 {
		b += 1 &lt;&lt; uint(idx)
	}
}
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:

确定