使用Go1.18泛型,自定义js数组

222 阅读1分钟
package collection

import "sync"

var rwMutex sync.RWMutex

type Item interface {
	any
}

// Array 自定义数组类型
type Array[T Item] []T

// Fn 自定义函数类型
type Fn[T Item] func(int, T, Array[T])
type FnBool[T Item] func(int, T, Array[T]) bool
type FnValue[T Item] func(int, T, Array[T]) T

// ForEach 遍历数组
func (a Array[T]) ForEach(fn Fn[T]) {
	for index, item := range a {
		fn(index, item, a)
	}
}

// Filter 返回回调函数满足条件的新数组
func (a Array[T]) Filter(fn FnBool[T]) *Array[T] {
	tempArray := make(Array[T], 0)
	for index, item := range a {
		if ok := fn(index, item, a); ok {
			tempArray = append(tempArray, item)
		}
	}
	return &tempArray
}

// Map 返回回调函数处理后的新数组
func (a Array[T]) Map(fn FnValue[T]) *Array[T] {
	// 提前申请好空间
	tempArray := make(Array[T], len(a))
	for index, item := range a {
		item := fn(index, item, a)
		tempArray = append(tempArray, item)
	}
	return &tempArray
}

// Pop 从尾部删除
func (a *Array[T]) Pop() T {
	rwMutex.Lock()
	defer rwMutex.Unlock()
	if len(*a) == 0 {
		panic("Array长度为0")
	}
	// 获取尾部元素
	last := (*a)[len(*a)-1]
	// 删除数组尾部元素
	*a = (*a)[:len(*a)-1]
	return last
}

// Push 从尾部追加
func (a *Array[T]) Push(items ...T) int {
	rwMutex.Lock()
	defer rwMutex.Unlock()
	*a = append(*a, items...)
	return len(items)
}

// Shift 从头部删除
func (a *Array[T]) Shift() T {
	rwMutex.Lock()
	defer rwMutex.Unlock()
	if len(*a) == 0 {
		panic("Array长度为0")
	}
	head := (*a)[0]
	*a = (*a)[1:len(*a)]
	return head
}

// Size 获取数组长度
func (a Array[T]) Size() int {
	return len(a)
}

// IsEmpty 数组是否为空
func (a Array[T]) IsEmpty() bool {
	return len(a) == 0
}