-
Notifications
You must be signed in to change notification settings - Fork 47
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Week 1 - Exercise #32
Comments
Version 2, để code nhìn rõ ràng hơn. package convert
import (
"bufio"
"errors"
"os"
"strconv"
"strings"
)
type City struct {
ID int
Name string
Districts []*District
}
type District struct {
ID int
Name string
Wards []Ward
}
type Ward struct {
ID int
Name string
}
var InvalidCSVData = errors.New("Invalid CSV Data")
var InvalidParseIDCity = errors.New("Invalid Parse ID City")
var InvalidParseIDDistrict = errors.New("Invalid Parse ID District")
var InvalidParseIDWard = errors.New("Invalid Parse ID Ward")
var citiMap = map[int]*City{}
var districtMap = map[int]*District{}
func processCity(cities *[]*City, id string, name string) (*City, error) {
ID, err := strconv.Atoi(id) //int
if err != nil {
return nil, InvalidParseIDCity
}
city, ok := citiMap[ID]
if !ok {
city = &City{
Name: name,
ID: ID,
}
citiMap[ID] = city
*cities = append(*cities, city)
}
return city, nil
}
func processDistrict(city *City, id string, name string) (*District, error) {
ID, err := strconv.Atoi(id) //int
if err != nil {
return nil, InvalidParseIDDistrict
}
district, ok := districtMap[ID]
if !ok {
district = &District{
Name: name,
ID: ID,
}
districtMap[ID] = district
city.Districts = append(city.Districts, district)
}
return district, nil
}
func processWard(district *District, id string, name string) error {
ID, err := strconv.Atoi(id) //int
if err != nil {
return InvalidParseIDWard
}
ward := Ward{
Name: name,
ID: ID,
}
district.Wards = append(district.Wards, ward)
return nil
}
// Private
func ConvertCSV2Yaml(file string) (cities []*City, err error) {
inFile, err := os.Open(file)
if err != nil {
return cities, err
}
// Hoc bua sau
defer inFile.Close()
//
scanner := bufio.NewScanner(inFile)
isFirstLine := false
for scanner.Scan() {
line := scanner.Text()
if isFirstLine == false {
isFirstLine = true
continue
}
cells := strings.Split(line, ",")
if len(cells) < 6 {
return cities, InvalidCSVData
}
// Xu ly cai city
city, err := processCity(&cities, cells[1], cells[0])
if err != nil {
return cities, err
}
// Xu ly district
district, err := processDistrict(city, cells[3], cells[2])
if err != nil {
return cities, InvalidParseIDDistrict
}
// Xu ly ward
err = processWard(district, cells[5], cells[4])
if err != nil {
return cities, InvalidParseIDWard
}
}
return cities, nil
} |
Version 3, phiên bản tổ chức tốt hơn package convert
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
type City struct {
ID int
Name string
Districts []*District
}
type District struct {
ID int
Name string
Wards []*Ward
}
type Ward struct {
ID int
Name string
}
type InvalidParserError interface {
error
GetTypeData() string
GetRawData() []string
}
type invalidParserErrorImp struct {
typeData string
rawData []string
}
func (e invalidParserErrorImp) Error() string {
return fmt.Sprintf("Invalid parser for %s, raw data are: %s",
e.typeData,
strings.Join(e.rawData, ","))
}
func (e invalidParserErrorImp) GetTypeData() string {
return e.typeData
}
func (e invalidParserErrorImp) GetRawData() []string {
return e.rawData
}
func NewInvalidParserError(typeData string, data ...string) InvalidParserError {
return invalidParserErrorImp{
typeData: typeData,
rawData: data,
}
}
var InvalidCSVData = func(data ...string) InvalidParserError {
return invalidParserErrorImp{
typeData: "line",
rawData: data,
}
}
var InvalidParseIDCity = func(data ...string) InvalidParserError {
return invalidParserErrorImp{
typeData: "city",
rawData: data,
}
}
var InvalidParseIDDistrict = func(data ...string) InvalidParserError {
return invalidParserErrorImp{
typeData: "district",
rawData: data,
}
}
var InvalidParseIDWard = func(data ...string) InvalidParserError {
return invalidParserErrorImp{
typeData: "ward",
rawData: data,
}
}
type CSVToYaml struct {
citiMap map[int]*City
districtMap map[int]*District
result []*City
}
func NewCSVToYamlConverter() CSVToYaml {
converter := CSVToYaml{
citiMap: map[int]*City{},
districtMap: map[int]*District{},
}
return converter
}
func (c *CSVToYaml) ConvertCSV2Yaml(file string) ([]*City, error) {
inFile, err := os.Open(file)
if err != nil {
return c.result, err
}
// Hoc bua sau
defer inFile.Close()
//
scanner := bufio.NewScanner(inFile)
isFirstLine := false
for scanner.Scan() {
line := scanner.Text()
if isFirstLine == false {
isFirstLine = true
continue
}
err := c.process(line)
if err != nil {
return c.result, err
}
}
return c.result, nil
}
func (c *CSVToYaml) process(line string) InvalidParserError {
cells := strings.Split(line, ",")
if len(cells) < 6 {
return InvalidCSVData(cells...)
}
// Xu ly cai city
city, err := c.processCity(cells[1], cells[0])
if err != nil {
return err
}
// Xu ly district
district, err := c.processDistrict(city, cells[3], cells[2])
if err != nil {
return err
}
// Xu ly ward
_, err = c.processWard(district, cells[5], cells[4])
return err
}
func (c *CSVToYaml) processCity(id string, name string) (*City, InvalidParserError) {
ID, err := strconv.Atoi(id) //int
if err != nil {
return nil, InvalidParseIDCity(id, name)
}
city, ok := c.citiMap[ID]
if !ok {
city = &City{
Name: name,
ID: ID,
}
c.citiMap[ID] = city
c.result = append(c.result, city)
}
return city, nil
}
func (c *CSVToYaml) processDistrict(city *City, id string, name string) (*District, InvalidParserError) {
ID, err := strconv.Atoi(id) //int
if err != nil {
return nil, InvalidParseIDDistrict(id, name)
}
district, ok := c.districtMap[ID]
if !ok {
district = &District{
Name: name,
ID: ID,
}
c.districtMap[ID] = district
city.Districts = append(city.Districts, district)
}
return district, nil
}
func (c *CSVToYaml) processWard(district *District, id string, name string) (*Ward, InvalidParserError) {
ID, err := strconv.Atoi(id) //int
if err != nil {
return nil, InvalidParseIDWard(id, name)
}
ward := &Ward{
Name: name,
ID: ID,
}
district.Wards = append(district.Wards, ward)
return ward, nil
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Unit 1
Convert CSV file to YAML file.
Input:
Data
Output:
Output
Unit 2
Port 5 functions of Lodash to Golang
The text was updated successfully, but these errors were encountered: