Golang排序时如何忽略特定字段

Golang排序时如何忽略特定字段 我的数据如下所示,我已能将其作为CSV读取并按时间排序,如下所示:

type Interface interface {
	Len() int
	Less(i, j int) bool
	Swap(i, j int)
}

func (t Transactions) Len() int { return len(t) }
func (t Transactions) Less(i, j int) bool {
	t1, _ := time.Parse("1/2/2006 03:04:05 PM", t[i].TrxTime)
	t2, _ := time.Parse("1/2/2006 03:04:05 PM", t[j].TrxTime)
	return t1.Before(t2)
}                                  
func (t Transactions) Swap(i, j int) { t[i], t[j] = t[j], t[i] }

它确实能按时间正确排序,但我发现它同时也按Warehouse进行了排序,输出结果如下:

I00003 20110  320 TRF-003009
I00003 20111  320 TRF-003009
I00003 20111 -320 TRF-003009
I00003 20119 -320 TRF-003009
I00003 20119 320 Opening

enter image description here

如何强制数据time排序而忽略其他参数,或者按timeQty排序,并强制忽略warehouse代码的考量?


更多关于Golang排序时如何忽略特定字段的实战教程也可以访问 https://www.itying.com/category-94-b0.html

2 回复

您没有提供可复现错误的代码和数据。因此,我们无法确定发生了什么。

看起来您根本没有进行排序。请务必检查错误。

hyousef:

t1, _ := time.Parse("1/2/2006 03:04:05 PM", t[i].TrxTime)
t2, _ := time.Parse("1/2/2006 03:04:05 PM", t[j].TrxTime)

03:04:05 PM15:04:05 是不同的。

hyousef: enter image description here

更多关于Golang排序时如何忽略特定字段的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


要实现仅按时间排序或按时间与数量排序而忽略仓库字段,可以使用以下两种方法:

方法1:仅按时间排序

func (t Transactions) Less(i, j int) bool {
    t1, _ := time.Parse("1/2/2006 03:04:05 PM", t[i].TrxTime)
    t2, _ := time.Parse("1/2/2006 03:04:05 PM", t[j].TrxTime)
    
    // 仅比较时间,完全忽略其他字段
    return t1.Before(t2)
}

方法2:按时间和数量排序(忽略仓库)

func (t Transactions) Less(i, j int) bool {
    t1, _ := time.Parse("1/2/2006 03:04:05 PM", t[i].TrxTime)
    t2, _ := time.Parse("1/2/2006 03:04:05 PM", t[j].TrxTime)
    
    // 首先比较时间
    if !t1.Equal(t2) {
        return t1.Before(t2)
    }
    
    // 时间相同的情况下比较数量
    return t[i].Qty < t[j].Qty
}

完整示例代码

package main

import (
    "fmt"
    "sort"
    "time"
)

type Transaction struct {
    TrxTime   string
    Qty       int
    Warehouse string
    // 其他字段...
}

type Transactions []Transaction

func (t Transactions) Len() int { return len(t) }

func (t Transactions) Swap(i, j int) { t[i], t[j] = t[j], t[i] }

// 仅按时间排序
func (t Transactions) LessByTimeOnly(i, j int) bool {
    t1, _ := time.Parse("1/2/2006 03:04:05 PM", t[i].TrxTime)
    t2, _ := time.Parse("1/2/2006 03:04:05 PM", t[j].TrxTime)
    return t1.Before(t2)
}

// 按时间和数量排序
func (t Transactions) LessByTimeAndQty(i, j int) bool {
    t1, _ := time.Parse("1/2/2006 03:04:05 PM", t[i].TrxTime)
    t2, _ := time.Parse("1/2/2006 03:04:05 PM", t[j].TrxTime)
    
    if !t1.Equal(t2) {
        return t1.Before(t2)
    }
    
    return t[i].Qty < t[j].Qty
}

func main() {
    transactions := Transactions{
        {"1/1/2023 10:00:00 AM", 320, "TRF-003009"},
        {"1/1/2023 10:00:00 AM", -320, "TRF-003009"},
        {"1/1/2023 09:00:00 AM", 320, "Opening"},
        {"1/1/2023 11:00:00 AM", 320, "TRF-003009"},
    }
    
    // 仅按时间排序
    sort.Slice(transactions, func(i, j int) bool {
        return transactions.LessByTimeOnly(i, j)
    })
    
    fmt.Println("按时间排序:")
    for _, t := range transactions {
        fmt.Printf("Time: %s, Qty: %d, Warehouse: %s\n", t.TrxTime, t.Qty, t.Warehouse)
    }
    
    // 按时间和数量排序
    sort.Slice(transactions, func(i, j int) bool {
        return transactions.LessByTimeAndQty(i, j)
    })
    
    fmt.Println("\n按时间和数量排序:")
    for _, t := range transactions {
        fmt.Printf("Time: %s, Qty: %d, Warehouse: %s\n", t.TrxTime, t.Qty, t.Warehouse)
    }
}

使用sort.Slice的简化版本

// 仅按时间排序
sort.Slice(transactions, func(i, j int) bool {
    t1, _ := time.Parse("1/2/2006 03:04:05 PM", transactions[i].TrxTime)
    t2, _ := time.Parse("1/2/2006 03:04:05 PM", transactions[j].TrxTime)
    return t1.Before(t2)
})

// 按时间和数量排序
sort.Slice(transactions, func(i, j int) bool {
    t1, _ := time.Parse("1/2/2006 03:04:05 PM", transactions[i].TrxTime)
    t2, _ := time.Parse("1/2/2006 03:04:05 PM", transactions[j].TrxTime)
    
    if !t1.Equal(t2) {
        return t1.Before(t2)
    }
    
    return transactions[i].Qty < transactions[j].Qty
})

关键点在于Less方法中只比较你关心的字段(时间和数量),完全不考虑仓库字段。这样排序算法就不会基于仓库字段进行任何比较操作。

回到顶部