如何在循环请求服务器时过滤重复int切片值,仅传递新值?
解决方案:用Map记录已处理值实现去重
最直接高效的方式是维护一个记录已处理数值的Map,利用Map的O(1)查找特性快速过滤重复值,具体实现如下:
基础单线程场景
在循环外部初始化一个空Map(用struct{}作为值,因为它不占用内存,比bool更高效),每次拿到服务器响应后,遍历切片筛选出未出现过的值:
package main import "fmt" func handleNewValues(values []int) { // 这里是下一个任务的处理逻辑 fmt.Println("传递新值:", values) } func main() { // 循环外维护已处理数值的Map processed := make(map[int]struct{}) // 模拟服务器响应1 resp1 := []int{1,2,3,4} var newValues1 []int for _, num := range resp1 { if _, exists := processed[num]; !exists { newValues1 = append(newValues1, num) processed[num] = struct{}{} } } handleNewValues(newValues1) // 输出:传递新值: [1 2 3 4] // 模拟服务器响应2 resp2 := []int{3,4,5,6} var newValues2 []int for _, num := range resp2 { if _, exists := processed[num]; !exists { newValues2 = append(newValues2, num) processed[num] = struct{}{} } } handleNewValues(newValues2) // 输出:传递新值: [5 6] }
并发场景注意事项
如果你的循环是在多goroutine中执行,必须给Map加锁避免并发写入panic,推荐用sync.RWMutex:
package main import ( "fmt" "sync" ) var ( processed = make(map[int]struct{}) mu sync.RWMutex // 读写锁,保证并发安全 ) func handleNewValues(values []int) { fmt.Println("传递新值:", values) } func processResponse(resp []int) { var newValues []int mu.Lock() defer mu.Unlock() for _, num := range resp { if _, exists := processed[num]; !exists { newValues = append(newValues, num) processed[num] = struct{}{} } } handleNewValues(newValues) } func main() { // 模拟并发处理响应 var wg sync.WaitGroup wg.Add(2) go func() { defer wg.Done() processResponse([]int{1,2,3,4}) }() go func() { defer wg.Done() processResponse([]int{3,4,5,6}) }() wg.Wait() }
持久化需求扩展
如果需要程序重启后不丢失已处理记录,可以把已处理数值存在Redis集合、本地文件或者数据库中:
- 用Redis的
SISMEMBER检查值是否存在,SADD添加新值; - 本地文件可以用JSON格式存储已处理切片,每次启动时加载到Map中。
内容的提问来源于stack exchange,提问作者RipOff
相关产品推荐
相关产品推荐

