mirror of
https://github.com/wahyd4/redhat.git
synced 2026-08-09 04:25:53 +10:00
81 lines
1.8 KiB
Go
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
|
|
}
|