Slice Find & Remove Cheat Sheet

This post is a cheat sheet for removing values from a Slice (technically creating a new slice).

Use case:

  • Allow 1 or more options, as an option is chosen it no longer becomes available as an option to choose

The code right here is the use case listed above used in one of my programs..

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
package main

import (
	"fmt"
	"strings"
	"bufio"
	"os"
)

func remove(s []string, i int) []string {
    s[len(s)-1], s[i] = s[i], s[len(s)-1]
    return s[:len(s)-1]
}

func Find(a []string, x string) int {
	for i, n := range a {
		if x == n {
			return i
		}
	}
	return len(a)
}

func main() {
    //slice to show options chosen
	var dataToAdd []string
	//creating reader for reading in input
	reader := bufio.NewReader(os.Stdin)
	//fields to select
	fieldsToChoose := []string{"created", "updated", "summary", "status", "priority", "assignee"}
	//unending loop until "ENTER" is pressed.
	for x := 0; x < 2; {
		fmt.Println("Please Enter Fields to print out")
		fmt.Println(fieldsToChoose)
		
		value, _ := reader.ReadString('\n')
		value = strings.TrimSpace(value)

		if value == "" {
			break
		}
		//remove chosen field from options list
		fieldsToChoose = remove(fieldsToChoose, Find(fieldsToChoose, value))
		//append option to a list of chosen options
		dataToAdd = append(dataToAdd, value)
		

	}
	fmt.Println(dataToAdd)
	
}

Slice General

Slices are a key data type in Go. Each key is a number and the value can be arbitrary.

A slice can be defined like:

1
testSlice := []string{"created", "updated", "summary", "status"} "priority", "assignee"}

Choosing a value from the Slice can be done with the integer location:

1
fmt.Println(testSlice[0])

Removing a value

Removing a value is not as easy as points to the location and giving it a blank value.

This will not work as intended, the BLANK value will still be there.

1
2
	testSlice [0] = ""
	fmt.Println(testSlice[0])

The correct way

This is a two step process.

1) Identifying the location of value you want to remove. 2) Creating a new slice without that value

A way I found on stackoverflow was using a slice of integers.

The idea is to swap the value you want removed with the last value in the slice and then create a new slice 1 size shorter. Thus dropping the last slice.

The example given is:

1
2
3
4
func remove(s []int, i int) []int {
    s[len(s)-1], s[i] = s[i], s[len(s)-1]
    return s[:len(s)-1]
}

The Go Playground code here

This works fine on supplying the location of the value. Hence why Step 1 is required.

Finding the location in the slice you want to remove

This finds the location of a string value within a slice:

1
2
3
4
5
6
7
8
func Find(a []string, x string) int {
	for i, n := range a {
		if x == n {
			return i
		}
	}
	return len(a)
}

Pass the function the slice you want to use and the string value you want to find and it will print its int position in the slice. such as:

The Go Playground code to try.

With the location identified we can pass it to the remove function above.

Finding and Removing

Lets work with a slice with strings: testSlice := []string{“apple”, “banana”, “orange”}

The remove function above has to be converted to allow strings. That means accepting strings and returning a string. It looks like:

1
2
3
4
5
6
func remove(s []string, i int) []string{
	s[i] = s[len(s)-1]
	fmt.Println("test",s[i])
	// We do not need to put s[i] at the end, as it will be discarded anyway
	return s[:len(s)-1]
}

So with the testSlice slice we will remove the string “banana”, which from above is the int location 1 in the slice.

1
2
3
4
5
func main() {
	testSlice := []string{"apple", "banana", "orange"}
	fmt.Println("Location of banana within testSlice")
	fmt.Println(Find(testSlice , "banana"))
}

We pass the 1 integer to the remove variable and we will have a new slice without the string banana.

This works here: The Go Playground

We can combine these together like so:

1
2
	testSlice := []string{"apple", "banana", "orange"}
	fmt.Println(remove(testSlice , Find(testSlice ,"banana")))

All the code together

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package main

import (
	"fmt"
)

func remove(s []string, i int) []string {
    s[len(s)-1], s[i] = s[i], s[len(s)-1]
    return s[:len(s)-1]
}

func Find(a []string, x string) int {
	for i, n := range a {
		if x == n {
			return i
		}
	}
	return len(a)
}


func main() {

	
	
	testSlice := []string{"apple", "banana", "orange"}
	fmt.Println("Find banana location and remove from slice (create new slice)")
	fmt.Println(remove(testSlice , Find(testSlice ,"banana")))
	
	
}

2020

Tcpdump Notes

I have been using tcpdump recently and wanted to note down some of the commands Y’know, for future reference.

Pivoting with SSH

Today I was trouble shooting a machine at work. I did not have access via RDP or VNC, so I used SSH to forward my traffic to the host so I could access a URL.

GitHub Actions

I participated in a DevSecOps type workshop on Saturday (May 9th) in which we created some GitHub Actions. This is a post to solidify the learning and be a c...

Threat Defense Workshop

On April 25th I was fortunate enough to participate in the Trend Micro Threat Defense workshop.

Incident Handling Certification

Since I blogged about my experience at OpenSoc, I wanted to expand on the value I found in my eLearnSecuirty Incident Response course. What you will find bel...

OpenSoc Experience

So Thursday (April 9th) I participated in an online blue team defense simulation event, known as OpenSOC.

Golang Parsing Strings

I have been working with Golang strings and how to manipulate them. Working from other blogs posts I’ve found. When I sit down to code, I seem to forget ever...

Welcome to Jekyll!

You’ll find this post in your _posts directory. Go ahead and edit it and re-build the site to see your changes. You can rebuild the site in many different wa...

Back to Top ↑