How to gob a map[string][]struct type?

690 views
Skip to first unread message

Sondre Naustdal

unread,
Jan 18, 2011, 12:59:00 PM1/18/11
to golan...@googlegroups.com


This code should store a map[string] []invert and load and print:
any suggestions are welcome

the functions contens and write_to are file I/O




package main

import(
"strings"
"os"
"gob"
"bytes"
"fmt"
)

type InvertMap map[string][]invert

type invert struct{
doc int
num int
}

func NewInvertMap() InvertMap {
return make(InvertMap)
}

func (im InvertMap) AddStemTo(doc []string, index int) (err os.Error) {


for i := range doc {
// if this is the first time the word is added
if im[doc[i]] == nil {
in := invert{doc:i, num:1}
im[doc[i]] = append(im[doc[i]],in)
} else {
chk := true
for j := range im[doc[i]] {
// if there already exist an inverted doc, just add to num
if im[doc[i]][j].doc == index {
im[doc[i]][j].num++
chk = false
}
}

if chk {
in := invert{doc:i, num:1}
im[doc[i]] = append(im[doc[i]],in)
// im[doc[i]] = append(im[doc[i]], index)
}

}

}
return nil
}

func (im *InvertMap) Load(im_filename string) (err os.Error) {

str, err := contents(im_filename)

b := bytes.NewBufferString(str)
dec := gob.NewDecoder(b)

dec.Decode(im)

return nil
}

func (im *InvertMap) Save(im_filename string) (err os.Error) {

b := new(bytes.Buffer)

enc := gob.NewEncoder(b)

err = enc.Encode(im)

if err != nil {
fmt.Printf("encode %s\n", err.String())
return
}

err = write_to(im_filename, b.Bytes())

if err != nil {
fmt.Printf("write %s\n", err.String())
return
}

return nil
}

func main (){
  
im1 := NewInvertMap()
im2 := NewInvertMap()
s := "words to have stored and returned to "
st := strings.Fields(s)
im1.AddStemTo(st,1)
im1.Save("store")
im2.Load("store")
for i := range im1 {
for j := range im1[i]{
println(im1[i][j].doc,im1[i][j].num)
}
}
for i := range im2 {
for j := range im2[i]{
println(im2[i][j].doc,im2[i][j].num)
}
}
}



--
When you have a hammer, everything looks like a nail!

peterGo

unread,
Jan 18, 2011, 10:16:29 PM1/18/11
to golang-nuts
Sondre,

> any suggestions are welcome

It looks to me as if, amongst other things, you are trying to
construct an inverted index of words in documents.
http://en.wikipedia.org/wiki/Inverted_index

Here's an example written in Go.

package main

import (
"fmt"
"strings"
)

type Reference struct {
docNo int
wordNo int
}

type Index map[string][]Reference

func (x Index) AddDoc(docNo int, doc string) {
for wordNo, word := range strings.Fields(doc) {
ref, ok := x[word]
if !ok {
ref = nil
}
x[word] = append(ref, Reference{docNo, wordNo})
}
}

func main() {
index := make(Index)
docNo := 0
doc := "words to have stored and returned to "
index.AddDoc(docNo, doc)
docNo = 1
doc = "have to too two two"
index.AddDoc(docNo, doc)
fmt.Println(index)
}

Peter

On Jan 18, 12:59 pm, Sondre Naustdal <sondre.naust...@gmail.com>
wrote:

peterGo

unread,
Jan 19, 2011, 12:34:47 AM1/19/11
to golang-nuts
Sondre,

Go Release 2011-01-12

The json, gob, and template packages have changed, and code that uses
them
may need to be updated after this release. They will no longer read or
write
unexported struct fields. When marshalling a struct with json or gob
the
unexported fields will be silently ignored. Attempting to unmarshal
json or
gob data into an unexported field will generate an error. Accessing an
unexported field from a template will cause the Execute function to
return
an error.

http://golang.org/doc/devel/release.html#2011-01-12

Here's a working example where gob is used to write and read an
inverted index where the struct fields are public.

package main

import (
"bytes"
"fmt"
"gob"
"os"
"strings"
)

type Reference struct {
DocNo int
WordNo int
}

type Index map[string][]Reference

func (x Index) AddDoc(DocNo int, doc string) {
for wordNo, word := range strings.Fields(doc) {
ref, ok := x[word]
if !ok {
ref = nil
}
x[word] = append(ref, Reference{DocNo, wordNo})
}
}

func EncodeAndDecode(in, out interface{}) os.Error {
b := new(bytes.Buffer)
enc := gob.NewEncoder(b)
err := enc.Encode(in)
if err != nil {
return err
}
dec := gob.NewDecoder(b)
err = dec.Decode(out)
if err != nil {
return err
}
return nil
}

func main() {
indexEnc := make(Index)
DocNo := 0
doc := "words to have stored and returned to "
indexEnc.AddDoc(DocNo, doc)
DocNo = 1
doc = "have to too two two"
indexEnc.AddDoc(DocNo, doc)
indexDec := make(Index)
err := EncodeAndDecode(indexEnc, &indexDec)
if err != nil {
fmt.Println(err)
}
fmt.Println(indexEnc)
fmt.Println(indexDec)
}

Peter

On Jan 18, 12:59 pm, Sondre Naustdal <sondre.naust...@gmail.com>
wrote:
Reply all
Reply to author
Forward
0 new messages