Insert value in a slice at given index

 ̄綄美尐妖づ 提交于 2020-01-30 04:12:09

问题


Given

array1 := []int{1, 3, 4, 5}
array2 := []int{2, 4, 6, 8}

I want to insert array2[2] i.e 6 at array1[1] i.e before 3 so that array1 becomes a slice of {1, 6, 3, 4, 5}. How can I do it?

Most the techniques I read online involve using the : operator but results in remaining elements being inserted as well. How can I append single values at an index in a slice?


回答1:


Simple, efficient and logical way:

  1. Make sure array1 has enough capacity (length) to accomodate the new, insertable element. To do that, append a single element using the builting append() (doesn't matter what that is, it'll get overwritten).
  2. To insert an element, existing elements must be shifted (copied over to 1 index higher) to make room for that element, e.g. using the builtin copy() (elements you want to insert before).
  3. Set the element at the proper index, using a single assignment.

In code:

array1 := []int{1, 3, 4, 5}
array2 := []int{2, 4, 6, 8}

array1 = append(array1, 0)   // Step 1
copy(array1[2:], array1[1:]) // Step 2
array1[1] = array2[2]        // Step 3

fmt.Println(array1)

Output (try it on the Go Playground):

[1 6 3 4 5]

Optimization in special cases

Note that in some special cases (when the slice element is big, like a big struct), it may be faster to append the last element, and then it's enough to copy 1 less elements (because the appended last element is right where it needs to be).

This is how it looks like:

last := len(array1) - 1
array1 = append(array1, array1[last]) // Step 1
copy(array1[2:], array1[1:last])      // Step 2
array1[1] = array2[2]                 // Step 3

This will result in the same slice. Try this one on the Go Playground.




回答2:


extending the answer from @Volker, i put the answer here https://play.golang.org/p/3Hla2y2ava too if you want to test it.

package main

import "fmt"

func main() {
    array1 := []int{1, 3, 4, 5}
    array2 := []int{2, 4, 6, 8}
    temp := append([]int{array2[2]}, array1[1:]...)
    array1 = append(array1[:1], temp...)
    fmt.Println(array1)
}



回答3:


I found the question setup pretty tricky to follow.

Rephrased, they want to insert an element. Here we have an array where it's missing the element 3 and we want to insert it.

package main

import (
    "fmt"
)

func main() {
    a := []int{1, 2, 4, 5, 6}
    b := 3

    // Make space in the array for a new element. You can assign it any value.
    a = append(a, 0)   
    fmt.Println(a)

    // Copy over elements sourced from index 2, into elements starting at index 3.
    copy(a[3:], a[2:])  
    fmt.Println(a)

    a[2] = b         
    fmt.Println(a)
}



回答4:


The following solution worked for me

func insert(a []int, c int, i int) []int {
    return append(a[:i], append([]int{c}, a[i:]...)...)
}

You can make it more general via empty interfaces

func insert(a []interface{}, c interface{}, i int) []interface{} {
    return append(a[:i], append([]interface{}{c}, a[i:]...)...)
}



回答5:


Based on icza's post i wrote a function to shift the slice / array which I want to share with you:

package main

import "fmt"

func main() {
    s := []string{"a", "c", "d"}
    shiftArray(&s, 1, "b")
    fmt.Println(s)

}

func shiftArray(array *[]string, position int, value string) {
    //  extend array by one
    *array = append(*array, "")

    // shift values
    copy((*array)[position+1:], (*array)[position:])

    // insert value
    (*array)[position] = value
}



回答6:


I answered a similar question in other thread. Anyway I used the following methods to play with slices and index:

func insertInt(array []int, value int, index int) []int {
    return append(array[:index], append([]int{value}, array[index:]...)...)
}

func removeInt(array []int, index int) []int {
    return append(array[:index], array[index+1:]...)
}

func moveInt(array []int, srcIndex int, dstIndex int) []int {
    value := array[srcIndex]
    return insertInt(removeInt(array, srcIndex), value, dstIndex)
}

You can play with it here:

https://play.golang.org/p/Sfu1VsySieS

I hope it'll help you




回答7:


I don't know is it optimal or not, but this piece of code works for me:

func sliceins(arr []int, pos int, elem int) []int { //insert element before pos in slice. if pos >= len(arr) insert into tail
    if pos < 0 {
        pos = 0
    } else if pos >= len(arr) {
        pos = len(arr)
    }
    out := make([]int, len(arr)+1)
    copy(out[:pos], arr[:pos])
    out[pos] = elem
    copy(out[pos+1:], arr[pos:])
    return out
}

In Your case just call

sliceins(array1, 1, array2[2])


来源:https://stackoverflow.com/questions/46128016/insert-value-in-a-slice-at-given-index

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!