go - superponer - Contiene el método para un corte
superponer graficas en r (7)
¿Hay algo similar a un slice.contains(object)
en Go sin tener que hacer una búsqueda a través de cada elemento en un sector?
En lugar de usar una slice
, el map
puede ser una mejor solución.
ejemplo simple:
package main
import "fmt"
func contains(slice []string, item string) bool {
set := make(map[string]struct{}, len(slice))
for _, s := range slice {
set[s] = struct{}{}
}
_, ok := set[item]
return ok
}
func main() {
s := []string{"a", "b"}
s1 := "a"
fmt.Println(contains(s, s1))
}
Mostafa ya ha señalado que tal método es trivial para escribir, y mkb le dio una pista para usar la búsqueda binaria del paquete de clasificación. Pero si vas a hacer muchos de estos controles, también podrías considerar usar un mapa.
Es trivial verificar si existe una clave de mapa específica usando el value, ok := yourmap[key]
idioma de value, ok := yourmap[key]
. Como no está interesado en el valor, también puede crear un map[string]struct{}
por ejemplo. Usar una struct{}
vacía aquí tiene la ventaja de que no requiere espacio adicional y el tipo de mapa interno de Go está optimizado para ese tipo de valores. Por lo tanto, map[string] struct{}
es una opción popular para conjuntos en el mundo Go.
No estoy seguro de que los medicamentos genéricos sean necesarios; solo necesita un contrato para su comportamiento deseado. Hacer lo siguiente no es más de lo que tendrías que hacer en otros idiomas si quisieras que quisieras que tus propios objetos se comportaran en colecciones, anulando Equals () y GetHashCode () por ejemplo.
type Identifiable interface{
GetIdentity() string
}
func IsIdentical(this Identifiable, that Identifiable) bool{
return (&this == &that) || (this.GetIdentity() == that.GetIdentity())
}
func contains(s []Identifiable, e Identifiable) bool {
for _, a := range s {
if IsIdentical(a,e) {
return true
}
}
return false
}
No, ese método no existe, pero es trivial de escribir:
func contains(s []int, e int) bool {
for _, a := range s {
if a == e {
return true
}
}
return false
}
Puede usar un mapa si esa búsqueda es una parte importante de su código, pero los mapas también lo han hecho.
Puede usar el paquete reflect para iterar sobre una interfaz cuyo tipo concreto es un sector:
func HasElem(s interface{}, elem interface{}) bool {
arrV := reflect.ValueOf(s)
if arrV.Kind() == reflect.Slice {
for i := 0; i < arrV.Len(); i++ {
// XXX - panics if slice element points to an unexported struct field
// see https://golang.org/pkg/reflect/#Value.Interface
if arrV.Index(i).Interface() == elem {
return true
}
}
}
return false
}
Si el sector está ordenado, hay una búsqueda binaria implementada en el paquete de sort
.
Si no es posible usar un mapa para buscar elementos basados en una clave, puede considerar la herramienta goderive . Goderive genera una implementación específica de tipo de un método contains, haciendo que su código sea legible y eficiente.
Ejemplo;
type Foo struct {
Field1 string
Field2 int
}
func Test(m Foo) bool {
var allItems []Foo
return deriveContainsFoo(allItems, m)
}
Para generar el método deriveContainsFoo:
- Instala Goderive con
go get -u github.com/awalterschulze/goderive
- Ejecute
goderive ./...
en su carpeta de espacio de trabajo
Este método se generará para derivarContains:
func deriveContainsFoo(list []Foo, item Foo) bool {
for _, v := range list {
if v == item {
return true
}
}
return false
}
Goderive tiene soporte para muchos otros métodos útiles de ayuda para aplicar un estilo de programación funcional en go.