英文:
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.:
<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>
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["rights"]
log.Println(formContains(rights, "create"))
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 & item) == item
}
See my complete example: 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
}
答案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{"create", "view", "edit", "delete"}
b := 0
for idx, key := range keys {
if len(r.Form[key]) != 0 {
b += 1 << uint(idx)
}
}
fmt.Printf("%04b", b)
use s := fmt.Sprintf("%04b", b)
to store the "binari rights string" into an string variable.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论