如何按两个值对地图排序?

时间:2019-07-19 15:20:49

标签: go

我试图按两个值对地图进行排序。首先是时间戳,然后是随机数。换句话说,我需要能够首先迭代并打印具有最小时间戳的地图,然后是nonce值。像这样:

html

这是我的代码:

https://play.golang.org/p/hXo5clCrlU1

    "tx1": Transaction{Value:10, Nonce:1, Timestamp:1563543005},
    "tx2": Transaction{Value:20, Nonce:2, Timestamp:1563543005},
    "tx6": Transaction{Value:60, Nonce:2, Timestamp:1563543005},
    "tx5": Transaction{Value:50, Nonce:4, Timestamp:1563543005},
    "tx7": Transaction{Value:70, Nonce:1, Timestamp:1563543006},
    "tx3": Transaction{Value:30, Nonce:3, Timestamp:1563543006},
    "tx4": Transaction{Value:40, Nonce:4, Timestamp:1563543006},

当前输出:

package main

import (
    "fmt"
    "sort"
)

type Transaction struct {
    Value         uint64                        `json:"value"`
    Nonce         uint64                        `json:"nonce"`
    Timestamp     int64                         `json:"timestamp"`
}

func main() {
    // To create a map as input
    memPool := map[string]Transaction {
        "tx1": Transaction{Value:10, Nonce:1, Timestamp:1563543005},
        "tx2": Transaction{Value:20, Nonce:2, Timestamp:1563543005},
        "tx3": Transaction{Value:30, Nonce:3, Timestamp:1563543006},
        "tx4": Transaction{Value:40, Nonce:4, Timestamp:1563543006},
        "tx5": Transaction{Value:50, Nonce:4, Timestamp:1563543005},
        "tx6": Transaction{Value:60, Nonce:2, Timestamp:1563543005},
        "tx7": Transaction{Value:70, Nonce:1, Timestamp:1563543006},
    }


    keys := make([]string, 0, len(memPool))
        for key := range memPool {
            keys = append(keys, key)
        }

        sort.Slice(keys, func(i, j int) bool { return memPool[keys[i]].Timestamp > memPool[keys[j]].Timestamp })


    for _, v := range keys {
        fmt.Println(v)
    }
    fmt.Println("")

    keys2 := make([]string, 0, len(memPool))
        for key2 := range memPool {
            keys2 = append(keys2, key2)
        }

    sort.Slice(keys2, func(i, j int) bool { return memPool[keys2[i]].Nonce > memPool[keys2[j]].Nonce })

    for _, v := range keys2 {
        fmt.Println(v)
    }

}

所需的输出:

tx7
tx3
tx4
tx1
tx2
tx5
tx6

tx4
tx5
tx3
tx6
tx2
tx7
tx1

2 个答案:

答案 0 :(得分:2)

您要对两个单独的时间进行排序,当您想对其进行一次排序时。因此,请使用您要用于对值进行排序的所有逻辑来进行一次排序。

sort.Slice(keys, func(i, j int) bool {
    if memPool[keys[i]].Timestamp == memPool[keys[j]].Timestamp {
        if memPool[keys[i]].Nonce == memPool[keys[j]].Nonce {
            return memPool[keys[i]].Value < memPool[keys[j]].Value
        }
        return memPool[keys[i]].Nonce < memPool[keys[j]].Nonce
    }
    return memPool[keys[i]].Timestamp < memPool[keys[j]].Timestamp
})

工作示例:https://play.golang.org/p/GERCSchEtOf

答案 1 :(得分:1)

同时比较两个搜索条件:

package main

import (
    "fmt"
    "sort"
)

type Transaction struct {
    Value         uint64                        `json:"value"`
    Nonce         uint64                        `json:"nonce"`
    Timestamp     int64                         `json:"timestamp"`
}

func main() {
    // To create a map as input
    memPool := map[string]Transaction {
        "tx1": Transaction{Value:10, Nonce:1, Timestamp:1563543005},
        "tx2": Transaction{Value:20, Nonce:2, Timestamp:1563543005},
        "tx3": Transaction{Value:30, Nonce:3, Timestamp:1563543006},
        "tx4": Transaction{Value:40, Nonce:4, Timestamp:1563543006},
        "tx5": Transaction{Value:50, Nonce:4, Timestamp:1563543005},
        "tx6": Transaction{Value:60, Nonce:2, Timestamp:1563543005},
        "tx7": Transaction{Value:70, Nonce:1, Timestamp:1563543006},
    }

    keys := make([]string, 0, len(memPool))
    for key := range memPool {
        keys = append(keys, key)
    }

    sort.Slice(keys, func(i, j int) bool {
        ti, tj := memPool[keys[i]], memPool[keys[j]]
        if ti.Timestamp == tj.Timestamp {
            return ti.Nonce < tj.Nonce
        }
        return ti.Timestamp < tj.Timestamp
    })

    for _, key := range keys {
        fmt.Println(memPool[key])
    }
}

https://play.golang.org/p/oFDG9Fti2JV

输出:

{10 1 1563543005}
{60 2 1563543005}
{20 2 1563543005}
{50 4 1563543005}
{70 1 1563543006}
{30 3 1563543006}
{40 4 1563543006}

观察如何实现less func(i, j int) bool的{​​{1}}参数:由于必须先按时间戳排序,然后按随机数排序,因此唯一必须考虑随机数的情况是时间戳相等时(否则)他们已经定义了要比较的元素的顺序。