I am very new go Golang and my question is not cleared also, but this is what I am trying to achieve. I have a csv file as follow, as I am mainly trying to re-arrange/sort last column(status=passed,failed/skipped)
test,test-cat,skipped
test,test-cat,failed
test,test-cat,passed
test,test-cat,skipped
test,test-cat,passed
test,test-cat,failed
Expecting last column to be grouped them together if it has same status.
test,test-cat,skipped
test,test-cat,skipped
test,test-cat,failed
test,test-cat,failed
test,test-cat,passed
test,test-cat,passed
With this codes I did, it does not look good:-) but it works as I wanted.
package main
import (
"bufio"
"fmt"
"os"
"strings"
)
func main() {
var FailStat, SkipStat,PassStat []string
file, err := os.Open("test.csv")
if err != nil {
fmt.Println(err)
} else {
scanner := bufio.NewScanner(file)
for scanner.Scan() {
line := scanner.Text()
if strings.Contains(line, "failed") {
FailStat = append(FailStat, line)
}
if strings.Contains(line, "skipped") {
SkipStat = append(SkipStat, line)
}
if strings.Contains(line, "passed") {
PassStat = append(PassStat, line)
}
}
}
file.Close()
var finalstat []string
finalstat = append(SkipStat, FailStat...)
finalstat = append(finalstat, PassStat...)
for _, line := range finalstat {
fmt.Println(line)
}
}
Test-Run:
$ ./readfile
test,test-cat,skipped
test,test-cat,skipped
test,test-cat,failed
test,test-cat,failed
test,test-cat,passed
test,test-cat,passed
There must be a many better ways, please advice. Sorry for newbie question!
CodePudding user response:
Inian's solution will work if the order of the status groupings doesn't matter (because of map's design, you should never expect to get the same ordering of the groups from run to run).
If you need the groups consistently ordered, that is actually sorted:
package main
import (
"encoding/csv"
"io"
"log"
"os"
"sort"
"strings"
)
type Row struct {
Name, Category, Status string
}
func main() {
in := `test,test-cat,skipped
test,test-cat,failed
test,test-cat,passed
test,test-cat,skipped
test,test-cat,passed
test,test-cat,failed
`
r := csv.NewReader(strings.NewReader(in))
rows := make([]Row, 0)
for {
record, err := r.Read()
if err == io.EOF {
break
}
if err != nil {
log.Fatal(err)
}
row := Row{record[0], record[1], record[2]}
rows = append(rows, row)
}
sort.Slice(rows, func(i, j int) bool { return rows[i].Status < rows[j].Status })
w := csv.NewWriter(os.Stdout)
for _, row := range rows {
w.Write([]string{row.Name, row.Category, row.Status})
}
w.Flush()
if err := w.Error(); err != nil {
log.Fatal(err)
}
}
and we get:
test,test-cat,failed
test,test-cat,failed
test,test-cat,passed
test,test-cat,passed
test,test-cat,skipped
test,test-cat,skipped
Change the < to > in the anonymous func for sort.Slice to reverse the order of the sort.
If you don't want to mess with the Row struct and convert between []Row and [][]string:
// ...
rows := make([][]string, 0)
for {
row, err := r.Read()
// ...
rows = append(rows, row)
}
sort.Slice(rows, func(i, j int) bool { return rows[i][2] < rows[j][2] })
w := csv.NewWriter(os.Stdout)
for _, row := range rows {
w.Write(row)
}
// ...
In a comment you mentioned wanting a specific order of the groups, and now I can in your original code what you were aiming for