英文:
Sorting slice of structs by big.Int value
问题
我有一个结构体列表,应该按照结构体的fee
值进行排序。我无法使用big.Int
和big.Float
,因为sort.Slice
无法处理这些类型。因此,我创建了compareAmount
变量,它是fee
的转换为浮点数版本,并将其用于排序。问题是发生了整数溢出(我猜测),因此我得到了错误的结果。附上的代码产生以下输出:
-2530185498501831 -2.530185498501831e+18
-1018378616691543 -1.018378616691543e+18
-867409028382366 -8.67409028382366e+17
-288718783870437 -2.88718783870437e+17
-190626693543325 -1.90626693543325e+17
-15553651457149158 2.8930926165603937e+18
对象应该按从高到低的顺序列出,所以我认为正确的结果应该是-190626693543325
是第一个元素,然后是-288718783870437
作为第二个元素,因为它们最接近0
。但是当我转换数字时发生了一些问题,列表没有按照我想要的方式排序。所以我的问题是,如何根据big.Int
的值对结构体切片进行排序,并产生这个输出:
-190626693543325 -1.90626693543325e+17
-288718783870437 -2.88718783870437e+17
-867409028382366 -8.67409028382366e+17
-1018378616691543 -1.018378616691543e+18
-2530185498501831 -2.530185498501831e+18
-15553651457149158 2.8930926165603937e+18
英文:
I have a list of structs which should be sorted by the fee
value of the structs. I couldn't use big.Int
and big.Float
because sort.Slice
won't work with these types. Therefore I created the compareAmount
variable which is the converted float version of fee
and use that for the sorting. The problem is that an integer overflow happens (I assume), therefore I get wrong results. The below attached code produces the following output:
-2530185498501831 -2.530185498501831e+18
-1018378616691543 -1.018378616691543e+18
-867409028382366 -8.67409028382366e+17
-288718783870437 -2.88718783870437e+17
-190626693543325 -1.90626693543325e+17
-15553651457149158 2.8930926165603937e+18
The objects should be listed from high to low, so I believe the correct result would be if -190626693543325
would be the first element, than -288718783870437
the second as these are closest to 0
. But something happens when I convert the numbers and the list is not sorted as I wanted. So my question is that how could I sort my slice of structs based on the big.Int
values and produce this output:
-190626693543325 -1.90626693543325e+17
-288718783870437 -2.88718783870437e+17
-867409028382366 -8.67409028382366e+17
-1018378616691543 -1.018378616691543e+18
-2530185498501831 -2.530185498501831e+18
-15553651457149158 2.8930926165603937e+18
package main
import (
"fmt"
"math/big"
"sort"
)
func divBigInt(num *big.Int) *big.Int {
divider := big.NewInt(1000)
divided := big.NewInt(0).Mul(num, divider)
return divided
}
type compareStruct struct {
fee *big.Int
compareAmount float64
}
func main() {
fee1 := big.NewInt(-288718783870437)
fee2 := big.NewInt(-867409028382366)
fee3 := big.NewInt(-190626693543325)
fee4 := big.NewInt(-1018378616691543)
fee5 := big.NewInt(-15553651457149158)
fee6 := big.NewInt(-2530185498501831)
fees := make([]*big.Int, 0)
fees = append(fees, fee1)
fees = append(fees, fee2)
fees = append(fees, fee3)
fees = append(fees, fee4)
fees = append(fees, fee5)
fees = append(fees, fee6)
feeList := make([]compareStruct, 0)
for _, f := range fees {
i1 := compareStruct{fee: f, compareAmount: float64(divBigInt(f).Int64())}
feeList = append(feeList, i1)
}
sort.Slice(feeList, func(i, j int) bool {
return feeList[i].compareAmount < feeList[j].compareAmount
})
for _, x := range feeList {
fmt.Println(x.fee, x.compareAmount)
}
}
答案1
得分: 3
big.Int
有一个Int.Cmp()
方法,所以你可以比较它们,这样你就可以直接对big.Int
值进行排序,而无需进行任何转换。为了按降序排序并获得你想要的输出:
sort.Slice(feeList, func(i, j int) bool {
return feeList[i].fee.Cmp(feeList[j].fee) > 0
})
在Go Playground上尝试一下。
另外,如果你只想对数字进行排序,那么不需要使用包装结构体的切片,你可以类似地对*big.Int
的切片进行排序。
英文:
big.Int
has an Int.Cmp()
method, so you can compare them, so you can directly sort big.Int
values without any conversion. To sort them descendant to get your desired output:
sort.Slice(feeList, func(i, j int) bool {
return feeList[i].fee.Cmp(feeList[j].fee) > 0
})
Try it on the Go Playground.
Also, if you just want to sort the numbers, the slice of wrapper structs is also needless, you can sort a slice of *big.Int
similarly.
答案2
得分: 1
你可以避免使用float64
字段,直接对数字进行排序:
package main
import (
"fmt"
"math/big"
"sort"
)
func main() {
fees := []*big.Int{
big.NewInt(-288718783870437),
big.NewInt(-867409028382366),
big.NewInt(-190626693543325),
big.NewInt(-1018378616691543),
big.NewInt(-15553651457149158),
big.NewInt(-2530185498501831),
}
sort.Slice(fees, func(a, b int) bool {
// sort direction high before low.
return fees[a].Cmp(fees[b]) > 0
})
fmt.Println("fees", fees)
}
英文:
You can avoid the need for the float64
field and just sort the numbers directly:
package main
import (
"fmt"
"math/big"
"sort"
)
func main() {
fees := []*big.Int{
big.NewInt(-288718783870437),
big.NewInt(-867409028382366),
big.NewInt(-190626693543325),
big.NewInt(-1018378616691543),
big.NewInt(-15553651457149158),
big.NewInt(-2530185498501831),
}
sort.Slice(fees, func(a, b int) bool {
// sort direction high before low.
return fees[a].Cmp(fees[b]) > 0
})
fmt.Println("fees", fees)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论