Go如何对数组切片进行去重

Go标准库自己没有提供一个去除slice中重复元素的函数,须要本身去实现。下面提供一种实现思路,若是有更好的实现方法欢迎留言讨论。php

package main

import (
    "fmt"
)

func main() {
    s := []string{"hello", "world", "hello", "golang", "hello", "ruby", "php", "java"}

    fmt.Println(removeDuplicateElement(s)) //output: hello world golang ruby php java
}

func removeDuplicateElement(languages []string) []string {
    result := make([]string, 0, len(languages))
    temp := map[string]struct{}{}
    for _, item := range languages {
        if _, ok := temp[item]; !ok {
            temp[item] = struct{}{}
            result = append(result, item)
        }
    }
    return result
}
复制代码

解释

  • removeDuplicateElement函数总共初始化两个变量,一个长度为0的slice,一个空map。因为slice传参是按引用传递,没有建立占用额外的内存空间。
  • map[string]struct{}{}建立了一个key类型为String值类型为空structmap,等效于使用make(map[string]struct{})
  • struct不占内存空间,使用它来实现咱们的函数空间复杂度是最低的。

Playground URL Reference URLjava

适配多个切片类型

上面的去除重复元素的函数,只能处理字符串切片对于其余类型的切片就不行了。若是不想针对每种类型的切片都写一个去重函数的话能够使用Go的type-switch本身写一个能够处理多个切片类型的函数。下面是我写的一个实现:git

package common

import (
	"fmt"
)


type sliceError struct {
	msg string
}

func (e *sliceError) Error() string {
	return e.msg
}

func Errorf(format string, args ...interface{}) error {
	msg := fmt.Sprintf(format, args...)
	return &sliceError{msg}
}

func removeDuplicateElement1(originals interface{}) (interface{}, error) {
	temp := map[string]struct{}{}
	switch slice := originals.(type) {
	case []string:
		result := make([]string, 0, len(originals.([]string)))
		for _, item := range slice {
			key := fmt.Sprint(item)
			if _, ok := temp[key]; !ok {
				temp[key] = struct{}{}
				result = append(result, item)
			}
		}
		return result, nil
	case []int64:
		result := make([]int64, 0, len(originals.([]int64)))
		for _, item := range slice {
			key := fmt.Sprint(item)
			if _, ok := temp[key]; !ok {
				temp[key] = struct{}{}
				result = append(result, item)
			}
		}
		return result, nil
	default:
		err := Errorf("Unknown type: %T", slice)
		return nil, err
	}
}
复制代码
  • 函数接收一个空接口类型的参数,而后使用类型选择进入相应的分支进行处理。这里能够根据需求添加函数需支持的切片类型的处理程序。github

  • 每一个分支里一样建立了一个key类型为string值类型为空structmap。key的值是切片元素的字符串表现形式(类型的String()方法的返回值)golang

  • 函数返回值的类型是空接口,因此拿到返回值后要进行类型断言才能使用。ruby

原文连接bash

相关文章
相关标签/搜索