2016-11-03 3 views
1

私はGoで意図的にマップを並べ替えていないことを知っていますが、私が取り組んでいるこの問題にはたくさんのメリットがあります。私の質問は、私はどのようにマップのFIFOスタイルを注文することができますか?これを実現しようとする価値があるのでしょうか?具体的には、私はインタフェースからうまく離れた構造のセットに非整列化できるようにしたいと思っています。ゴールンFIFOをアンマーシャリング中に注文する方法

現在、私が持っている:私がやりたい何

type Package struct { 
    Account string 
    Jobs  []*Jobs 
    Libraries map[string]string 
} 

type Jobs struct { 
// Name of the job 
    JobName string `mapstructure:"name" json:"name" yaml:"name" toml:"name"` 
// Type of the job. should be one of the strings outlined in the job struct (below) 
    Job *Job `mapstructure:"job" json:"job" yaml:"job" toml:"job"` 
// Not marshalled 
    JobResult string 
// For multiple values 
    JobVars []*Variable 
} 

type Job struct { 
// Sets/Resets the primary account to use 
    Account *Account `mapstructure:"account" json:"account" yaml:"account" toml:"account"` 
// Set an arbitrary value 
    Set *Set `mapstructure:"set" json:"set" yaml:"set" toml:"set"` 
// Contract compile and send to the chain functions 
    Deploy *Deploy `mapstructure:"deploy" json:"deploy" yaml:"deploy" toml:"deploy"` 
// Send tokens from one account to another 
    Send *Send `mapstructure:"send" json:"send" yaml:"send" toml:"send"` 
// Utilize eris:db's native name registry to register a name 
    RegisterName *RegisterName `mapstructure:"register" json:"register" yaml:"register" toml:"register"` 
// Sends a transaction which will update the permissions of an account. Must be sent from an account which 
// has root permissions on the blockchain (as set by either the genesis.json or in a subsequence transaction) 
    Permission *Permission `mapstructure:"permission" json:"permission" yaml:"permission" toml:"permission"` 
// Sends a bond transaction 
    Bond *Bond `mapstructure:"bond" json:"bond" yaml:"bond" toml:"bond"` 
// Sends an unbond transaction 
    Unbond *Unbond `mapstructure:"unbond" json:"unbond" yaml:"unbond" toml:"unbond"` 
// Sends a rebond transaction 
    Rebond *Rebond `mapstructure:"rebond" json:"rebond" yaml:"rebond" toml:"rebond"` 
// Sends a transaction to a contract. Will utilize eris-abi under the hood to perform all of the heavy lifting 
    Call *Call `mapstructure:"call" json:"call" yaml:"call" toml:"call"` 
// Wrapper for mintdump dump. WIP 
    DumpState *DumpState `mapstructure:"dump-state" json:"dump-state" yaml:"dump-state" toml:"dump-state"` 
// Wrapper for mintdum restore. WIP 
    RestoreState *RestoreState `mapstructure:"restore-state" json:"restore-state" yaml:"restore-state" toml:"restore-state"` 
// Sends a "simulated call" to a contract. Predominantly used for accessor functions ("Getters" within contracts) 
    QueryContract *QueryContract `mapstructure:"query-contract" json:"query-contract" yaml:"query-contract" toml:"query-contract"` 
// Queries information from an account. 
    QueryAccount *QueryAccount `mapstructure:"query-account" json:"query-account" yaml:"query-account" toml:"query-account"` 
// Queries information about a name registered with eris:db's native name registry 
    QueryName *QueryName `mapstructure:"query-name" json:"query-name" yaml:"query-name" toml:"query-name"` 
// Queries information about the validator set 
    QueryVals *QueryVals `mapstructure:"query-vals" json:"query-vals" yaml:"query-vals" toml:"query-vals"` 
// Makes and assertion (useful for testing purposes) 
    Assert *Assert `mapstructure:"assert" json:"assert" yaml:"assert" toml:"assert"` 
} 

は仕事を持っている仕事に文字列のマップを含み、それらは設定から​​配置された順序を維持しながら、jobフィールドを排除ファイル。 (現在バイパーを使用しています)。これを達成するためのあらゆる提案は大歓迎です。

+0

関連/重複する可能性(のhttp:/ /stackoverflow.com/questions/28930416/why-cant-goiterate-maps-in-insertion-order); [Golang map in order range loop](http://stackoverflow.com/questions/39450120/golang-map-in-order-range-loop)を参照してください。 – icza

答えて

4

キーを別のスライスに保持し、それを使用する必要があります。あなたがviperを使用している場合

type fifoJob struct { 
    m map[string]*Job 
    order []string 
    result []string 
    // Not sure where JobVars will go. 
} 

func (str *fifoJob) Enqueue(key string, val *Job) { 
    str.m[key] = val 
    str.order = append(str.order, key) 
} 

func (str *fifoJob) Dequeue() { 
    if len(str.order) > 0 { 
     delete(str.m, str.order[0]) 
     str.order = str.order[1:] 
    } 
} 

とにかく、あなたは上で定義されfifoJob構造体のようなものを使用することができます。また、私はここでいくつかの仮定をしています。

type Package struct { 
    Account string 
    Jobs  *fifoJob 
    Libraries map[string]string 
} 

var config Package 
config.Jobs = fifoJob{} 
config.Jobs.m = map[string]*Job{} 

// Your config file would need to store the order in an array. 
// Would've been easy if viper had a getSlice method returning []interface{} 
config.Jobs.order = viper.GetStringSlice("package.jobs.order") 

for k,v := range viper.GetStringMap("package.jobs.jobmap") { 

    if job, ok := v.(Job); ok { 
     config.Jobs.m[k] = &job 
    } 
} 

PS用:あなたは、あなたの質問では、あまりにも多くの無関係な詳細を与えています。私はMCVEを求めていた。

+0

迅速な対応をありがとう。 FIFOによる反復可能なマッピングを可能にするjsonリストのために簡単に非マーシャル可能なものを作ることへの私の希望は、容易ではなく、おそらくatmを無視するのが最善であるように思えます。しかし、ありがとう。これは多くの助けとなりました。 –

+0

'json.Unmarshaler'インターフェースを実装すれば可能です。しかし、それがいかに簡単かは、あなたの正確な問題にかかっています。 –

+2

マップが大きい場合は、ソートされたキーのリストを維持することで処理が遅くなることに注意してください。私は10Mのエントリのオーダーでハッシュマップを使ってこの問題にぶつかり、このアプローチを考え直さなければならなかった。結局、結合されたハッシュマップとキューのデータ構造は魅力的に機能しました。 – johnzachary

0

マップの性質上、順序は異なりますが、キーではなくスライスを塗りつぶすことができます。次に、スライスの範囲を広げ、好きなように並べ替えることができます。スライス内の特定の要素を[i]で取り出すことができます。

チェックアウトページ170、203、または本のいくつかの素晴らしい例の204:

Programming in Go

[なぜ、挿入順に反復マップを行くことができないのですか?]の
関連する問題