Files
redhat/analyse.go
2020-01-14 11:48:36 +11:00

81 lines
1.8 KiB
Go

package redhat
import (
"bufio"
"fmt"
"os"
"sort"
"strings"
)
// HandleLine the custom func type for processing a line and push data into the map
type HandleLine func(contentMap map[string]int, line string)
// AnalyseData analyse data with sort, uniq and sort by count
func (fa *FileAnalyser) AnalyseData() error {
contentMap, err := fa.parseContent(fa.file, processLineWithWhiteSpace)
if err != nil {
return err
}
fa.transformFromMapToDataRows(contentMap)
fa.sortDataRows()
return nil
}
func (fa *FileAnalyser) parseContent(file *os.File, handler HandleLine) (map[string]int, error) {
contentMap := make(map[string]int)
scanner := bufio.NewScanner(file)
defer file.Close()
for scanner.Scan() {
handler(contentMap, scanner.Text())
}
if err := scanner.Err(); err != nil {
return nil, fmt.Errorf("fail to read and process content: %s", err.Error())
}
return contentMap, nil
}
func (fa *FileAnalyser) sortDataRows() {
sort.SliceStable(fa.dataRows, func(i, j int) bool {
if firstItemHasMoreCount(fa, i, j) {
return true
}
return compareRowsWhenAreSameCount(fa, i, j)
})
}
func (fa *FileAnalyser) transformFromMapToDataRows(contentMap map[string]int) {
for key, value := range contentMap {
fa.dataRows = append(fa.dataRows, dataRow{
word: key,
count: value,
})
}
}
func processLineWithWhiteSpace(contentMap map[string]int, line string) {
words := strings.Fields(line)
for _, word := range words {
count, ok := contentMap[word]
if !ok {
contentMap[word] = 1
continue
}
contentMap[word] = count + 1
}
}
func firstItemHasMoreCount(fa *FileAnalyser, i int, j int) bool {
return fa.dataRows[i].count > fa.dataRows[j].count
}
func compareRowsWhenAreSameCount(fa *FileAnalyser, i int, j int) bool {
return (fa.dataRows[i].count == fa.dataRows[j].count) && fa.dataRows[i].word > fa.dataRows[j].word
}