In Go, how can I partition a slice/array/string of any type?

huangapple go评论87阅读模式
英文:

In Go, how can I partition a slice/array/string of any type?

问题

Guava有一个通用的分区方法,由于Go语言缺乏泛型支持,无法直接在Go中实现。是否有解决方法?

英文:

Guava has a generic partition method which can not directly be implemented in Go due to Go's lack of generics. Is there a workaround for this?

答案1

得分: 6

gopart库可以解决这个问题。它允许对任何可索引的Go对象进行分区,无论其类型如何。

for idxRange := range gopart.Partition(len(bigList), partitionSize) {
    bulkOperation(bigList[idxRange.Low:idxRange.High])
}

完整可执行示例

英文:

The gopart library addresses this. It allows partitioning of anything indexable in Go that has any type.

for idxRange := range gopart.Partition(len(bigList), partitionSize) {
        bulkOperation(bigList[idxRange.Low:idxRange.High])
}

Full Executable Example

答案2

得分: 1

我发现这个问题和答案,因为我需要相同的解决方案,但在我创建了已经存在的东西之前。

然而,我并不喜欢这个解决方案的性能,所以我创建了一个速度更快、更灵活的实现包。

为了提高速度,我使用了一个作为回调函数传递给函数的函数,而不是使用通道。我还添加了使用切片和接口的实现,以及一个通道实现,以比较所有这些方法的性能,并给用户灵活选择他们需要的方法。

为了防止其他人也需要创建自己的实现,我将其公开在以下网址:https://github.com/crosscode-nl/partition

根据代码的基准测试显示,基于通道的解决方案比函数版本慢。

示例用法:

a := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
partition.ToFunc(len(a), 5, func(l int, h int) {
fmt.Printf("Part: %v\n", a[l:h])
})
// 输出:
// Part: [1 2 3 4 5]
// Part: [6 7 8 9]

有关详细信息,请参见存储库中的基准测试。

英文:

I found this question and answer because I needed the same solution, before I created something that already exists.

I did, however, not like the performance of the solution, so I created a package with a faster and more flexible implementation.

To improve the speed, instead of using channels I used a function that is passed to the function as a callback for the results. I also added implementations using slices and an interface, as well as a channel one to compare the performance of all those methods and give users the flexibility to use the method they require.

To prevent others also need to create their own implementation I made it publicly available at the following url: https://github.com/crosscode-nl/partition

According a benchmark of the code shows that the channel based solution is slower than the func version.

BenchmarkToChan100-4      	   50000	     25862 ns/op
BenchmarkToChan10-4       	  300000	      4939 ns/op
BenchmarkToChan0-4        	  500000	      2727 ns/op
BenchmarkToFunc100-4      	 5000000	       230 ns/op
BenchmarkToFunc10-4       	30000000	        46.5 ns/op
BenchmarkToFunc0-4        	100000000	        14.6 ns/op

Example usage:

a := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
partition.ToFunc(len(a), 5, func(l int, h int) {
	fmt.Printf("Part: %v\n", a[l:h])
})
// Output:
// Part: [1 2 3 4 5]
// Part: [6 7 8 9]

See benchmarks in repo for details.

huangapple
  • 本文由 发表于 2015年5月15日 00:34:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/30242567.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定