Kurt Peek
Kurt Peek

Reputation: 57761

How to make a slice from a mapset.Set?

I'm reading Donovan's "The Go Programming Language" book and trying to implement an exercise which prints duplicate lines from several files and the files in which they occur:

package main

import (
    "fmt"
    "io/ioutil"
    "os"
    "strings"

    mapset "github.com/deckarep/golang-set"
)

func main() {
    counts := make(map[string]int)
    occurrences := make(map[string]mapset.Set)
    for _, filename := range os.Args[1:] {
        data, err := ioutil.ReadFile(filename)
        if err != nil {
            fmt.Fprintf(os.Stderr, "dup3: %v\n", err)
            continue
        }
        for _, line := range strings.Split(string(data), "\n") {
            counts[line]++
            occurrences[line].Add(filename)
        }
    }
    for line, n := range counts {
        if n > 1 {
            fmt.Printf("%d\t%s\t%s\n", n, line, strings.Join(occurrences[line], ", "))
        }
    }
}

To accomplish the exercise, I've used the https://godoc.org/github.com/deckarep/golang-set package. However, I'm not sure how to print out the elements of the set joined by a ", ". With this code, I get a

./hello.go:23:30: first argument to append must be slice; have interface { Add(interface {}) bool; Cardinality() int; CartesianProduct(mapset.Set) mapset.Set; Clear(); Clone() mapset.Set; Contains(...interface {}) bool; Difference(mapset.Set) mapset.Set; Each(func(interface {}) bool); Equal(mapset.Set) bool; Intersect(mapset.Set) mapset.Set; IsProperSubset(mapset.Set) bool; IsProperSuperset(mapset.Set) bool; IsSubset(mapset.Set) bool; IsSuperset(mapset.Set) bool; Iter() <-chan interface {}; Iterator() *mapset.Iterator; Pop() interface {}; PowerSet() mapset.Set; Remove(interface {}); String() string; SymmetricDifference(mapset.Set) mapset.Set; ToSlice() []interface {}; Union(mapset.Set) mapset.Set }
./hello.go:28:64: cannot use occurrences[line] (type mapset.Set) as type []string in argument to strings.Join

I wasn't able to easily find out how to convert the Set to a slice though. Any idea how I might accomplish this?

Upvotes: 1

Views: 1238

Answers (1)

peterSO
peterSO

Reputation: 166895

The XY problem is asking about your attempted solution rather than your actual problem: The XY Problem.


The Go Programming Language by Alan A. A. Donovan and Brian W. Kernighan, Exercise 1.4 is designed to use Go maps.

For example,

// Modify dup3 to print the names of all files in which each duplicated line occurs.
package main

import (
    "fmt"
    "io/ioutil"
    "os"
    "strings"
)

func main() {
    // counts = [line][file]count
    counts := make(map[string]map[string]int)
    for _, filename := range os.Args[1:] {
        data, err := ioutil.ReadFile(filename)
        if err != nil {
            fmt.Fprintf(os.Stderr, "Exercise 1.4: %v\n", err)
            continue
        }
        for _, line := range strings.Split(string(data), "\n") {
            files := counts[line]
            if files == nil {
                files = make(map[string]int)
                counts[line] = files
            }
            files[filename]++
        }
    }
    for line, files := range counts {
        n := 0
        for _, count := range files {
            n += count
        }
        if n > 1 {
            fmt.Printf("%d\t%s\n", n, line)
            for name := range files {
                fmt.Printf("%s\n", name)
            }
        }
    }
}

Upvotes: 2

Related Questions