首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Go中惯用的切片拼接?

Go中惯用的切片拼接?
EN

Stack Overflow用户
提问于 2012-11-25 02:45:40
回答 4查看 3.2K关注 0票数 4

我有以下用于实现拼接的代码(即,给定一个字节片完整,另一个字节片部分,以及一个表示我想要用部分覆盖的完整位置的int pos ):

代码语言:javascript
运行
复制
package main

import (
    "fmt"
    "bytes"
)

func main() {
    full := []byte{0,0,0,0,0,0,0}
    part := []byte{1,1,1}

    newFull1 := splice(full, part, 2)
    fmt.Println(newFull1)
    // [0 0 1 1 1 0 0]

    newFull2 := splice(full, part, 3)
    fmt.Println(newFull2)
    // [0 0 0 1 1 1 0]
}

func splice(full []byte, part []byte, pos int) []byte {
    return bytes.Join([][]byte{full[:pos], part, full[len(full[:pos])+len(part):]}, []byte{})
}

基本上,我的方法连接3个字节的切片: full的第一部分不会被part覆盖,all of part,然后是full的其余部分。有没有更好/更地道的方法来做这件事?我在标准库中找不到实现这一点的方法。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-11-25 03:11:00

如果您知道零件完全在full的范围内,则可以使用复制功能。

代码语言:javascript
运行
复制
func main() {
    full := []byte{0, 0, 0, 0, 0, 0, 0}
    part := []byte{1, 1, 1}

    copy(full[2:], part)
    fmt.Println(full)
}

playground

不过,这会覆盖full。如果你想保留原件,你可以先用append函数复制一份。

代码语言:javascript
运行
复制
func main() {
    full := []byte{0, 0, 0, 0, 0, 0, 0}
    part := []byte{1, 1, 1}

    newFull := append([]byte{}, full...)
    copy(newFull[2:], part)
    fmt.Println("newFull:      ", newFull)
    fmt.Println("original full:", full)
}

playground

注意,这仍然有您的原始代码的限制,该部分必须在full的范围内。

票数 6
EN

Stack Overflow用户

发布于 2021-10-11 05:15:25

这是另一个用于拼接字节片的变体。该算法类似于Anton Litvinov的stringSplice()。因为append函数与输入共享相同的切片,所以必须使用与输入长度相同的副本。这不是由前一个答案中的“beatgammit”完成的,它不能正常工作。

代码语言:javascript
运行
复制
package main

import "fmt"

func sliceSplice(input []byte, start, deleteCount int, item []byte) ([]byte) {
    fmt.Printf("input:      %v start = %d deleteCount = %d item: %v\n", input, start, deleteCount, item)
    cpy := make([]byte, len(input))
    copy(cpy, input)
    fmt.Println("cpy:       ", cpy)
    if start > len(cpy) {
        return append(cpy, item...)
    }
    ret := append(cpy[:start], item...)
    fmt.Println("ret:       ", ret)

    if start+deleteCount > len(cpy) {
        return ret
    }
    fmt.Println("cpy:       ", cpy, "       modified by shared slice 'ret'")
    fmt.Println("input[s+d] ", input[start+deleteCount:], "         not modified")
    return append(ret, input[start+deleteCount:]...)
}

func main() {
    oldFull := []byte{0, 0, 1, 1, 1, 0, 0}
    fmt.Println("oldFull:      ", oldFull, "\n")
    myFull := sliceSplice(oldFull, 3, 0, []byte{2, 2})
    fmt.Println("myFull:       ", myFull, "\n")
    myFull = sliceSplice(oldFull, 3, 1, []byte{2, 2})
    fmt.Println("myFull:       ", myFull, "\n")
    myFull = sliceSplice(oldFull, 3, 4, []byte{2, 2})
    fmt.Println("myFull:       ", myFull, "\n")
    myFull = sliceSplice(oldFull, 3, 6, []byte{2, 2})
    fmt.Println("myFull:       ", myFull, "\n")
    myFull = sliceSplice(oldFull, 7, 0, []byte{2, 2})
    fmt.Println("myFull:       ", myFull, "\n")
    myFull = sliceSplice(oldFull, 9, 6, []byte{2, 2})
    fmt.Println("myFull:       ", myFull, "\n")
}

我还包含了一组测试用例。

票数 1
EN

Stack Overflow用户

发布于 2012-11-25 03:57:11

为什么不使用内置的append

代码语言:javascript
运行
复制
func splice(full, part []byte, pos int) (ret []byte) {
    ret = append(full[:pos], part...)
    return append(ret, full[pos:]...)
}

这可能不是很快(大量复制),但它是相当可读的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13544374

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档