xxxxxxxxxx
package main
import (
"bytes"
"encoding/csv"
"fmt"
"io/fs"
"log"
"os"
"sync"
)
func main() {
buf, err := fs.ReadFile(os.DirFS("."), "demo2.csv")
if err != nil {
log.Fatal(err)
}
csvReader := csv.NewReader(bytes.NewBuffer(buf))
records, err := csvReader.ReadAll()
if err != nil {
log.Fatal(err)
}
data := parseCsv(records)
for _, v := range data {
fmt.Println(v)
}
}
func parseCsv(record [][]string) []map[string]interface{} {
headers := record[:1][0]
recordLength := len(record)
records := record[1:recordLength]
return reformatCsv(headers, records)
}
func reformatCsv(headers []string, record [][]string) []map[string]interface{} {
var (
mutex *sync.Mutex = new(sync.Mutex)
wg *sync.WaitGroup = new(sync.WaitGroup)
csvRecord map[string]interface{} = make(map[string]interface{})
csvRecordLength int = len(record)
)
if csvRecordLength == 0 {
return nil
}
if csvRecordLength == 1 {
for i, v := range headers {
csvRecord[v] = record[0][i]
}
return []map[string]interface{}{csvRecord}
}
mid := len(record) / 2
records := make(chan ([]map[string]interface{}))
semanpro := make(chan bool, 1000)
semanpro <- true
wg.Add(1)
go func(records chan []map[string]interface{}) {
defer func() {
<-semanpro
}()
wg.Done()
left := reformatCsv(headers, record[:mid])
right := reformatCsv(headers, record[mid:])
mutex.Lock()
defer mutex.Unlock()
records <- append(left, right )
}(records)
wg.Wait()
return <-records
}
xxxxxxxxxx
func CsvRecursive(headers []string, record [][]string) []map[string]interface{} {
csvRecordLength := len(record)
csvRecord := make(map[string]interface{})
if csvRecordLength == 0 {
return nil
}
if csvRecordLength == 1 {
for i, v := range headers {
csvRecord[v] = record[0][i]
}
return []map[string]interface{}{csvRecord}
}
mid := len(record) / 2
left := CsvRecursive(headers, record[:mid])
right := CsvRecursive(headers, record[mid:])
return append(left, right )
}
func CsvRecursive(headers []string, records [][]string) []map[string]interface{} {
var wg sync.WaitGroup
recordCount := len(records)
csvRecords := make([]map[string]interface{}, recordCount)
for i, record := range records {
wg.Add(1)
go func(i int, record []string) {
csvRecord := make(map[string]interface{})
for j, header := range headers {
csvRecord[header] = record[j]
}
csvRecords[i] = csvRecord
wg.Done()
}(i, record)
}
wg.Wait()
return csvRecords
}
xxxxxxxxxx
package main
import (
"bytes"
"encoding/csv"
"fmt"
"io/fs"
"log"
"os"
"sync"
)
func main() {
buf, err := fs.ReadFile(os.DirFS("."), "demo2.csv")
if err != nil {
log.Fatal(err)
}
csvReader := csv.NewReader(bytes.NewBuffer(buf))
record, err := csvReader.ReadAll()
headers := record[:1][0]
recordLength := len(record)
records := record[1:recordLength]
data := CsvRecursive(headers, records)
for _, v := range data {
fmt.Println(v)
}
}
func CsvRecursive(headers []string, record [][]string) []map[string]interface{} {
var (
mutex *sync.Mutex = new(sync.Mutex)
csvRecord map[string]interface{} = make(map[string]interface{})
csvRecordLength int = len(record)
)
if csvRecordLength == 0 {
return nil
}
if csvRecordLength == 1 {
for i, v := range headers {
csvRecord[v] = record[0][i]
}
return []map[string]interface{}{csvRecord}
}
mid := len(record) / 2
records := make(chan ([]map[string]interface{}))
go func(records chan []map[string]interface{}) {
left := CsvRecursive(headers, record[:mid])
right := CsvRecursive(headers, record[mid:])
mutex.Lock()
defer mutex.Unlock()
records <- append(left, right )
}(records)
return <-records
}