¿Hay algo similar a un método slice.contains(object)
en Go sin tener que hacer una búsqueda a través de cada elemento en un sector?Contiene el método para un segmento
Respuesta
Mostafa ya ha señalado que dicho método es trivial de 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 comprobar si existe una clave de mapa específica utilizando la expresión value, ok := yourmap[key]
. Como no está interesado en el valor, también puede crear un map[string]struct{}
por ejemplo. Usar un struct{}
vacío 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 los sets en el mundo Go.
+1 para explicar bien la solución del mapa. – Mostafa
no estoy 100% seguro de cómo funciona todo esto, (esta es prácticamente mi primera oportunidad en GO) pero parece ser lo que estoy buscando. ¡Gracias! – vosmith
También tenga en cuenta que debe escribir 'struct {} {}' para obtener el valor de la estructura vacía para que pueda pasarla a su mapa cuando desee agregar un elemento. Pruébelo y si tiene algún problema, no dude en preguntar. También puede usar la solución de Mostafa si es más fácil de comprender (a menos que tenga grandes cantidades de datos). – tux21b
Si el corte está ordenado, hay una búsqueda binaria implementada en the sort
package.
No, tal método no existe, pero es trivial para escribir:
func contains(s []int, e int) bool {
for _, a := range s {
if a == e {
return true
}
}
return false
}
Se puede utilizar un mapa si es que las operaciones de búsqueda es una parte importante de su código, pero los mapas de haber costado demasiado.
En realidad no es trivial, porque usted tiene que escribir una para cada tipo que se utiliza, y porque no hay sobrecarga, hay que nombrar a cada función de manera diferente, como en C. append() puede funcionar genéricamente porque tiene soporte de tiempo de ejecución especial. Un contenido genérico sería útil por la misma razón, pero realmente la solución genérica es solo soporte de genéricos en el lenguaje. – Eloff
@Eloff 'interfaz {}' –
@Alex Lockwood ¿funcionará realmente con las interfaces? –
En lugar de utilizar un slice
, map
puede ser una solución mejor.
ejemplo sencillo:
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))
}
En su forma actual, este código no ofrece ningún beneficio, ya que no tiene sentido construir un mapa a partir de una porción si solo va a utilizarlo una vez. - Para ser útil, este código debería proporcionar una función 'sliceToMap' que hace toda la preparación. Después de eso, consultar el mapa es trivial y eficiente. –
Gracias por el código de muestra. – xpt
Puede utilizar el reflejan paquete para iterar sobre una interfaz cuyo tipo concreto es una rebanada:
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
}
No estoy seguro de que los genéricos sean necesarios aquí, 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
}
- 1. LINQ Contiene método para un objeto
- 2. Colección/matriz contiene el método
- 3. 'Clase' no contiene una definición para 'Método'
- 4. Detectando el segmento interceptado de un UISegmentedControl
- 5. C++ Segmento seguro para subprocesos
- 6. ¿Por qué no puedo editar un método que contiene un método anónimo en el depurador?
- 7. El programa no contiene un método estático "Principal" adecuado para un punto de entrada
- 8. encargo de ArrayList Contiene método
- 9. HashSet contiene método, extraño comportamiento
- 10. nuevo error de arquitectura ios6: el archivo es universal (3 sectores) pero no contiene un segmento (n) arm7vs
- 11. Permisos AWS IAM básicos para un segmento S3
- 12. ¿Para qué se utiliza el segmento HL7 ZDS?
- 13. búsqueda de mysql para el segmento del nombre de tabla
- 14. ¿Por qué puedo actualizar un segmento de lista pero no un segmento de cadena en python?
- 15. de recursos que no se encuentra para el segmento 'Propiedad'
- 16. ¿Por qué HTML Canvas redondea lineCap para el último segmento?
- 17. ¿Cómo calculo el vector normal de un segmento de línea?
- 18. Error CS5001: exe no contiene un método estático `Principal 'adecuado para un punto de entrada
- 19. Método de refactorización que contiene consultas LINQ
- 20. cuán rápido es el segmento de python
- 21. Calcula la distancia promedio de un segmento de punto a otro y de un segmento de línea a un segmento de línea
- 22. En un idioma OO, ¿cuál es el nombre de su clase que contiene el método principal?
- 23. cómo volver a montar el segmento tcp?
- 24. nombre de la clase que contiene el código de método
- 25. ¿Puedo usar una lambda incrustada con el método Contiene?
- 26. entendimiento contiene método de Java HashSet
- 27. Obtener el segundo segmento de la url
- 28. Segmento-polígono intersección
- 29. ¿Cómo obtengo el objeto Método para un método?
- 30. ¿Qué método de comprobación para ver si un NSDictionary contiene una clave particular es más rápido?
https://github.com/forestgiant/sliceutil – Rodrigo