fmt.Println("Enter position to delete::")
fmt.Scanln(&pos)
new_arr := make([]int, (len(arr) - 1))
k := 0
for i := 0; i < (len(arr) - 1); {
if i != pos {
new_arr[i] = arr[k]
k++
i++
} else {
k++
}
}
for i := 0; i < (len(arr) - 1); i++ {
fmt.Println(new_arr[i])
}
J'utilise cette commande pour supprimer un élément d'une tranche mais cela ne fonctionne pas, veuillez suggérer.
Réponses:
L'ordre compte
Si vous voulez garder votre tableau ordonné, vous devez décaler tous les éléments à droite de l'index de suppression de un vers la gauche. Espérons que cela peut être fait facilement à Golang:
func remove(slice []int, s int) []int { return append(slice[:s], slice[s+1:]...) }
Cependant, cela est inefficace car vous pouvez finir par déplacer tous les éléments, ce qui est coûteux.
L'ordre n'est pas important
Si vous ne vous souciez pas de la commande, vous avez la possibilité beaucoup plus rapide d'échanger l'élément à supprimer avec celui à la fin de la tranche, puis de renvoyer les n-1 premiers éléments:
func remove(s []int, i int) []int { s[len(s)-1], s[i] = s[i], s[len(s)-1] return s[:len(s)-1] }
Avec la méthode de reslicing, vider un tableau de 1 000 000 éléments prend 224s, avec celui-ci, cela ne prend que 0,06ns. Je soupçonne qu'en interne, aller ne change que la longueur de la tranche, sans la modifier.
Modifier 1
Notes rapides basées sur les commentaires ci-dessous (merci à eux!).
Comme le but est de supprimer un élément, lorsque l'ordre n'a pas d'importance, un seul swap est nécessaire, le second sera gaspillé:
func remove(s []int, i int) []int { s[i] = s[len(s)-1] // We do not need to put s[i] at the end, as it will be discarded anyway return s[:len(s)-1] }
De plus, cette réponse n'effectue pas de vérification des limites . Il attend un index valide en entrée. Cela signifie que des valeurs négatives ou des indices supérieurs ou égaux à len (s) provoqueront la panique de Go. Les tranches et les tableaux étant indexés à 0, la suppression du n-ième élément d'un tableau implique de fournir une entrée n-1 . Pour supprimer le premier élément, appelez remove (s, 0) , pour supprimer le second, appelez remove (s, 1) , et ainsi de suite.
la source
s[i] = s[len(s)-1]; return s[:len(s)-1]
suffirait.return s[1:]
lequel ne répond pas non plus à la question d'origine.s[i] = s[len(s)-1]
copie définitivement le dernier élément dans l'élément à l'indexi
. Ensuite,return s[:len(s)-1]
renvoie la tranche sans le dernier élément. Deux déclarations là-bas.Supprimez un élément de la tranche (c'est ce qu'on appelle 're-slicing'):
package main import ( "fmt" ) func RemoveIndex(s []int, index int) []int { return append(s[:index], s[index+1:]...) } func main() { all := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9} fmt.Println(all) //[0 1 2 3 4 5 6 7 8 9] all = RemoveIndex(all, 5) fmt.Println(all) //[0 1 2 3 4 6 7 8 9] }
la source
2019/09/28 19:46:25 http: panic serving 192.168.1.3:52817: runtime error: slice bounds out of range [7:5] goroutine 7 [running]:
panic
si l'index est le dernier élément de la tranchePoint mineur (code golf), mais dans le cas où l'ordre n'a pas d'importance, vous n'avez pas besoin d'échanger les valeurs. Remplacez simplement la position du tableau supprimée par un double de la dernière position, puis renvoyez un tableau tronqué.
func remove(s []int, i int) []int { s[i] = s[len(s)-1] return s[:len(s)-1] }
Même résultat.
la source
s[i] = s[0]
, puis de renvoyer un tableau avec uniquement les n-1 derniers éléments.return s[1:]
s[1:]
contres[:len(s)-1]
est que ce dernier fonctionnera beaucoup mieux si la tranche plus tard estappend
modifiée ou si les suppressions sont mélangées avecappend
s. Le dernier garde la capacité de tranche là où, contrairement au premier.C'est un peu étrange à voir, mais la plupart des réponses ici sont dangereuses et ignorent ce qu'elles font réellement. En regardant la question d'origine qui a été posée sur la suppression d'un élément de la tranche, une copie de la tranche est en cours de création, puis remplie. Cela garantit que lorsque les tranches sont transmises à votre programme, vous n'introduisez pas de bogues subtils.
Voici un code comparant les réponses des utilisateurs dans ce fil de discussion et dans l'article original. Voici un terrain de jeu pour jouer avec ce code.
Ajouter la suppression basée
package main import ( "fmt" ) func RemoveIndex(s []int, index int) []int { return append(s[:index], s[index+1:]...) } func main() { all := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9} fmt.Println("all: ", all) //[0 1 2 3 4 5 6 7 8 9] removeIndex := RemoveIndex(all, 5) fmt.Println("all: ", all) //[0 1 2 3 4 6 7 8 9 9] fmt.Println("removeIndex: ", removeIndex) //[0 1 2 3 4 6 7 8 9] removeIndex[0] = 999 fmt.Println("all: ", all) //[999 1 2 3 4 6 7 9 9] fmt.Println("removeIndex: ", removeIndex) //[999 1 2 3 4 6 7 8 9] }
Dans l'exemple ci-dessus, vous pouvez me voir créer une tranche et la remplir manuellement avec les nombres 0 à 9. Nous supprimons ensuite l'index 5 de tous et l'assignons pour supprimer l'index. Cependant, lorsque nous allons tout imprimer maintenant, nous voyons qu'il a également été modifié. En effet, les tranches sont des pointeurs vers un tableau sous-jacent. L'écrire dans les
removeIndex
causesall
à modifier également avec la différence étantall
est plus long par un élément qui n'est plus accessible à partir deremoveIndex
. Ensuite, nous changeons une valeur dansremoveIndex
et nous pouvons voir qu'elleall
est également modifiée. Efficace va plus en détail à ce sujet.Je n'entrerai pas dans l'exemple suivant, mais il fait la même chose pour nos besoins. Et illustre simplement que l'utilisation de la copie n'est pas différente.
package main import ( "fmt" ) func RemoveCopy(slice []int, i int) []int { copy(slice[i:], slice[i+1:]) return slice[:len(slice)-1] } func main() { all := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9} fmt.Println("all: ", all) //[0 1 2 3 4 5 6 7 8 9] removeCopy := RemoveCopy(all, 5) fmt.Println("all: ", all) //[0 1 2 3 4 6 7 8 9 9] fmt.Println("removeCopy: ", removeCopy) //[0 1 2 3 4 6 7 8 9] removeCopy[0] = 999 fmt.Println("all: ", all) //[99 1 2 3 4 6 7 9 9] fmt.Println("removeCopy: ", removeCopy) //[999 1 2 3 4 6 7 8 9] }
Les questions réponse originale
En regardant la question d'origine, cela ne modifie pas la tranche dont il supprime un élément. Faire de la réponse originale dans ce fil la meilleure à ce jour pour la plupart des gens qui viennent sur cette page.
package main import ( "fmt" ) func OriginalRemoveIndex(arr []int, pos int) []int { new_arr := make([]int, (len(arr) - 1)) k := 0 for i := 0; i < (len(arr) - 1); { if i != pos { new_arr[i] = arr[k] k++ } else { k++ } i++ } return new_arr } func main() { all := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9} fmt.Println("all: ", all) //[0 1 2 3 4 5 6 7 8 9] originalRemove := OriginalRemoveIndex(all, 5) fmt.Println("all: ", all) //[0 1 2 3 4 5 6 7 8 9] fmt.Println("originalRemove: ", originalRemove) //[0 1 2 3 4 6 7 8 9] originalRemove[0] = 999 fmt.Println("all: ", all) //[0 1 2 3 4 5 6 7 8 9] fmt.Println("originalRemove: ", originalRemove) //[999 1 2 3 4 6 7 8 9] }
Comme vous pouvez le voir, cette sortie agit comme la plupart des gens s'y attendraient et probablement ce que la plupart des gens veulent. La modification de
originalRemove
n'entraîne pas de changements dansall
et l'opération de suppression de l'index et de son attribution n'entraîne pas non plus de changements! Fantastique!Ce code est un peu long, donc ce qui précède peut être changé en cela.
Une bonne réponse
package main import ( "fmt" ) func RemoveIndex(s []int, index int) []int { ret := make([]int, 0) ret = append(ret, s[:index]...) return append(ret, s[index+1:]...) } func main() { all := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9} fmt.Println("all: ", all) //[0 1 2 3 4 5 6 7 8 9] removeIndex := RemoveIndex(all, 5) fmt.Println("all: ", all) //[0 1 2 3 4 5 6 7 8 9] fmt.Println("removeIndex: ", removeIndex) //[0 1 2 3 4 6 7 8 9] removeIndex[0] = 999 fmt.Println("all: ", all) //[0 1 2 3 4 5 6 7 9 9] fmt.Println("removeIndex: ", removeIndex) //[999 1 2 3 4 6 7 8 9] }
Presque identique à la solution originale de suppression d'index, mais nous créons une nouvelle tranche à ajouter avant de revenir.
la source
all
est également modifiée aprèsremoveIndex := RemoveIndex(all, 5)
car append réutilise le même tableau sous-jacent s'il a une capacité suffisante (la suppression d'un élément ne nécessite bien sûr pas plus de capacité). Inversement, si nous ajoutons des éléments et les attribuonsremoveIndex
, append allouera un nouveau tableau etall
ne changera pas.C'est ainsi que vous supprimez d' une tranche à la manière du golang . Vous n'avez pas besoin de créer une fonction, elle est intégrée à l'append. Essayez-le ici https://play.golang.org/p/QMXn9-6gU5P
z := []int{9, 8, 7, 6, 5, 3, 2, 1, 0} fmt.Println(z) //will print Answer [9 8 7 6 5 3 2 1 0] z = append(z[:2], z[4:]...) fmt.Println(z) //will print Answer [9 8 5 3 2 1 0]
la source
Extrait du livre The Go Programming Language
la source
Je prends l'approche ci-dessous pour supprimer l'élément en tranche. Cela contribue à la lisibilité pour les autres. Et aussi immuable.
func remove(items []string, item string) []string { newitems := []string{} for _, i := range items { if i != item { newitems = append(newitems, i) } } return newitems }
la source
Peut-être que vous pouvez essayer cette méthode:
// DelEleInSlice delete an element from slice by index // - arr: the reference of slice // - index: the index of element will be deleted func DelEleInSlice(arr interface{}, index int) { vField := reflect.ValueOf(arr) value := vField.Elem() if value.Kind() == reflect.Slice || value.Kind() == reflect.Array { result := reflect.AppendSlice(value.Slice(0, index), value.Slice(index+1, value.Len())) value.Set(result) } }
Usage:
arrInt := []int{0, 1, 2, 3, 4, 5} arrStr := []string{"0", "1", "2", "3", "4", "5"} DelEleInSlice(&arrInt, 3) DelEleInSlice(&arrStr, 4) fmt.Println(arrInt) fmt.Println(arrStr)
Résultat:
0, 1, 2, 4, 5 "0", "1", "2", "3", "5"
la source
Peut-être que ce code vous aidera.
Il supprime l'élément avec un index donné.
Prend le tableau et l'index à supprimer et renvoie un nouveau tableau à peu près comme la fonction d'ajout.
func deleteItem(arr []int, index int) []int{ if index < 0 || index >= len(arr){ return []int{-1} } for i := index; i < len(arr) -1; i++{ arr[i] = arr[i + 1] } return arr[:len(arr)-1] }
Ici, vous pouvez jouer avec le code: https://play.golang.org/p/aX1Qj40uTVs
la source
la meilleure façon de le faire est d'utiliser la fonction append:
package main import ( "fmt" ) func main() { x := []int{4, 5, 6, 7, 88} fmt.Println(x) x = append(x[:2], x[4:]...)//deletes 6 and 7 fmt.Println(x) }
https://play.golang.org/p/-EEFCsqse4u
la source
Trouvez un moyen ici sans déménager.
a := []string{"A", "B", "C", "D", "E"} i := 2 // Remove the element at index i from a. a[i] = a[len(a)-1] // Copy last element to index i. a[len(a)-1] = "" // Erase last element (write zero value). a = a[:len(a)-1] // Truncate slice. fmt.Println(a) // [A B E D]
a := []string{"A", "B", "C", "D", "E"} i := 2 // Remove the element at index i from a. copy(a[i:], a[i+1:]) // Shift a[i+1:] left one index. a[len(a)-1] = "" // Erase last element (write zero value). a = a[:len(a)-1] // Truncate slice. fmt.Println(a) // [A B D E]
la source
Pas besoin de vérifier chaque élément sauf si vous vous souciez du contenu et que vous pouvez utiliser slice append. Essaye le
pos := 0 arr := []int{1, 2, 3, 4, 5, 6, 7, 9} fmt.Println("input your position") fmt.Scanln(&pos) /* you need to check if negative input as well */ if (pos < len(arr)){ arr = append(arr[:pos], arr[pos+1:]...) } else { fmt.Println("position invalid") }
la source
voici l'exemple de terrain de jeu avec des pointeurs. https://play.golang.org/p/uNpTKeCt0sH
package main import ( "fmt" ) type t struct { a int b string } func (tt *t) String() string{ return fmt.Sprintf("[%d %s]", tt.a, tt.b) } func remove(slice []*t, i int) []*t { copy(slice[i:], slice[i+1:]) return slice[:len(slice)-1] } func main() { a := []*t{&t{1, "a"}, &t{2, "b"}, &t{3, "c"}, &t{4, "d"}, &t{5, "e"}, &t{6, "f"}} k := a[3] a = remove(a, 3) fmt.Printf("%v || %v", a, k) }
la source