mirror of
https://github.com/duke-git/lancet.git
synced 2025-10-28 17:41:50 +08:00
refactor: update signature of WriteMapsToCsv function
g
This commit is contained in:
@@ -706,6 +706,8 @@ import "github.com/duke-git/lancet/v2/fileutil"
|
|||||||
[[play](https://go.dev/play/p/OExTkhGEd3_u)]
|
[[play](https://go.dev/play/p/OExTkhGEd3_u)]
|
||||||
- **<big>WriteCsvFile</big>** : write content to target csv file.
|
- **<big>WriteCsvFile</big>** : write content to target csv file.
|
||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/fileutil.md#WriteCsvFile)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/fileutil.md#WriteCsvFile)]
|
||||||
|
- **<big>WriteMapsToCsv</big>** : write slice of map to csv file.
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/fileutil.md#WriteMapsToCsv)]
|
||||||
[[play](https://go.dev/play/p/dAXm58Q5U1o)]
|
[[play](https://go.dev/play/p/dAXm58Q5U1o)]
|
||||||
- **<big>WriteBytesToFile</big>** : write bytes to target file.
|
- **<big>WriteBytesToFile</big>** : write bytes to target file.
|
||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/fileutil.md#WriteBytesToFile)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/en/api/packages/fileutil.md#WriteBytesToFile)]
|
||||||
|
|||||||
@@ -705,8 +705,10 @@ import "github.com/duke-git/lancet/v2/fileutil"
|
|||||||
- **<big>ReadCsvFile</big>** : 读取 csv 文件内容到切片。
|
- **<big>ReadCsvFile</big>** : 读取 csv 文件内容到切片。
|
||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/fileutil.md#ReadCsvFile)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/fileutil.md#ReadCsvFile)]
|
||||||
[[play](https://go.dev/play/p/OExTkhGEd3_u)]
|
[[play](https://go.dev/play/p/OExTkhGEd3_u)]
|
||||||
- **<big>WriteCsvFile</big>** : 向 csv 文件写入内容。
|
- **<big>WriteCsvFile</big>** : 向csv文件写入切片数据。
|
||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/fileutil.md#WriteCsvFile)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/fileutil.md#WriteCsvFile)]
|
||||||
|
- **<big>WriteMapsToCsv</big>** : 将map切片写入csv文件中。
|
||||||
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/fileutil.md#WriteMapsToCsv)]
|
||||||
[[play](https://go.dev/play/p/dAXm58Q5U1o)]
|
[[play](https://go.dev/play/p/dAXm58Q5U1o)]
|
||||||
- **<big>WriteBytesToFile</big>** : 将 bytes 写入文件。
|
- **<big>WriteBytesToFile</big>** : 将 bytes 写入文件。
|
||||||
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/fileutil.md#WriteBytesToFile)]
|
[[doc](https://github.com/duke-git/lancet/blob/main/docs/api/packages/fileutil.md#WriteBytesToFile)]
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ import (
|
|||||||
- [Sha](#Sha)
|
- [Sha](#Sha)
|
||||||
- [ReadCsvFile](#ReadCsvFile)
|
- [ReadCsvFile](#ReadCsvFile)
|
||||||
- [WriteCsvFile](#WriteCsvFile)
|
- [WriteCsvFile](#WriteCsvFile)
|
||||||
|
- [WriteMapsToCsv](#WriteMapsToCsv)
|
||||||
- [WriteStringToFile](#WriteStringToFile)
|
- [WriteStringToFile](#WriteStringToFile)
|
||||||
- [WriteBytesToFile](#WriteBytesToFile)
|
- [WriteBytesToFile](#WriteBytesToFile)
|
||||||
- [ReadFile](#ReadFile)
|
- [ReadFile](#ReadFile)
|
||||||
@@ -754,7 +755,8 @@ func main() {
|
|||||||
// records: 写入文件的map切片。map值必须为基本类型。会以map键的字母顺序写入。
|
// records: 写入文件的map切片。map值必须为基本类型。会以map键的字母顺序写入。
|
||||||
// appendToExistingFile: 是否为追加写模式。
|
// appendToExistingFile: 是否为追加写模式。
|
||||||
// delimiter: CSV文件分割符。
|
// delimiter: CSV文件分割符。
|
||||||
func WriteMapsToCsv(filepath string, records []map[string]string, append_to_existing_file bool, delimiter ...rune) error
|
// headers: CSV文件表头顺序(需要与map key保持一致),不指定时按字母排序。
|
||||||
|
func WriteMapsToCsv(filepath string, records []map[string]any, appendToExistingFile bool, delimiter rune, headers ...[]string) error
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>示例:</b>
|
<b>示例:</b>
|
||||||
@@ -779,7 +781,8 @@ func main() {
|
|||||||
{"Name": "Jim", "Age": "21", "Gender": "male"},
|
{"Name": "Jim", "Age": "21", "Gender": "male"},
|
||||||
}
|
}
|
||||||
|
|
||||||
err := fileutil.WriteMapsToCsv(csvFilePath, records, false, ';')
|
headers := []string{"Name", "Age", "Gender"}
|
||||||
|
err := WriteMapsToCsv(csvFilePath, records, false, ';', headers)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
@@ -790,7 +793,7 @@ func main() {
|
|||||||
fmt.Println(content)
|
fmt.Println(content)
|
||||||
|
|
||||||
// Output:
|
// Output:
|
||||||
// [[Age Gender Name] [22 female Lili] [21 male Jim]]
|
// [[Name Age Gender] [Lili 22 female] [Jim 21 male]]
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ import (
|
|||||||
- [Sha](#Sha)
|
- [Sha](#Sha)
|
||||||
- [ReadCsvFile](#ReadCsvFile)
|
- [ReadCsvFile](#ReadCsvFile)
|
||||||
- [WriteCsvFile](#WriteCsvFile)
|
- [WriteCsvFile](#WriteCsvFile)
|
||||||
|
- [WriteCsvFile](#WriteCsvFile)
|
||||||
- [WriteMapsToCsv](#WriteMapsToCsv)
|
- [WriteMapsToCsv](#WriteMapsToCsv)
|
||||||
- [WriteStringToFile](#WriteStringToFile)
|
- [WriteStringToFile](#WriteStringToFile)
|
||||||
- [WriteBytesToFile](#WriteBytesToFile)
|
- [WriteBytesToFile](#WriteBytesToFile)
|
||||||
@@ -755,7 +756,8 @@ func main() {
|
|||||||
// records: slice of maps to be written. the value of map should be basic type. The maps will be sorted by key in alphabeta order, then be written into csv file.
|
// records: slice of maps to be written. the value of map should be basic type. The maps will be sorted by key in alphabeta order, then be written into csv file.
|
||||||
// appendToExistingFile: If true, data will be appended to the file if it exists.
|
// appendToExistingFile: If true, data will be appended to the file if it exists.
|
||||||
// delimiter: Delimiter to use in the CSV file.
|
// delimiter: Delimiter to use in the CSV file.
|
||||||
func WriteMapsToCsv(filepath string, records []map[string]string, append_to_existing_file bool, delimiter ...rune) error
|
// headers: order of the csv column headers, needs to be consistent with the key of the map.
|
||||||
|
func WriteMapsToCsv(filepath string, records []map[string]any, appendToExistingFile bool, delimiter rune, headers ...[]string) error
|
||||||
```
|
```
|
||||||
|
|
||||||
<b>Example:</b>
|
<b>Example:</b>
|
||||||
@@ -780,7 +782,8 @@ func main() {
|
|||||||
{"Name": "Jim", "Age": "21", "Gender": "male"},
|
{"Name": "Jim", "Age": "21", "Gender": "male"},
|
||||||
}
|
}
|
||||||
|
|
||||||
err := fileutil.WriteMapsToCsv(csvFilePath, records, false, ';')
|
headers := []string{"Name", "Age", "Gender"}
|
||||||
|
err := fileutil.WriteMapsToCsv(csvFilePath, records, false, ';', headers)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
@@ -791,7 +794,7 @@ func main() {
|
|||||||
fmt.Println(content)
|
fmt.Println(content)
|
||||||
|
|
||||||
// Output:
|
// Output:
|
||||||
// [[Age Gender Name] [22 female Lili] [21 male Jim]]
|
// [[Name Age Gender] [Lili 22 female] [Jim 21 male]]
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -760,7 +760,9 @@ func escapeCSVField(field string, delimiter rune) string {
|
|||||||
// the maps will be sorted by key in alphabeta order, then be written into csv file.
|
// the maps will be sorted by key in alphabeta order, then be written into csv file.
|
||||||
// appendToExistingFile: If true, data will be appended to the file if it exists.
|
// appendToExistingFile: If true, data will be appended to the file if it exists.
|
||||||
// delimiter: Delimiter to use in the CSV file.
|
// delimiter: Delimiter to use in the CSV file.
|
||||||
func WriteMapsToCsv(filepath string, records []map[string]any, appendToExistingFile bool, delimiter ...rune) error {
|
// headers: order of the csv column headers, needs to be consistent with the key of the map.
|
||||||
|
func WriteMapsToCsv(filepath string, records []map[string]any, appendToExistingFile bool, delimiter rune,
|
||||||
|
headers ...[]string) error {
|
||||||
for _, record := range records {
|
for _, record := range records {
|
||||||
for _, value := range record {
|
for _, value := range record {
|
||||||
if !isCsvSupportedType(value) {
|
if !isCsvSupportedType(value) {
|
||||||
@@ -769,40 +771,31 @@ func WriteMapsToCsv(filepath string, records []map[string]any, appendToExistingF
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var datasToWrite [][]string
|
var columnHeaders []string
|
||||||
|
if len(headers) > 0 {
|
||||||
// 标题(列名)
|
columnHeaders = headers[0]
|
||||||
var headers []string
|
} else {
|
||||||
if len(records) > 0 {
|
|
||||||
for key := range records[0] {
|
for key := range records[0] {
|
||||||
headers = append(headers, key)
|
columnHeaders = append(columnHeaders, key)
|
||||||
}
|
}
|
||||||
|
// sort keys in alphabeta order
|
||||||
|
sort.Strings(columnHeaders)
|
||||||
}
|
}
|
||||||
|
|
||||||
// sort keys in alphabeta order
|
var datasToWrite [][]string
|
||||||
sort.Strings(headers)
|
|
||||||
|
|
||||||
// 追加模式不重复写字段名
|
|
||||||
if !appendToExistingFile {
|
if !appendToExistingFile {
|
||||||
datasToWrite = append(datasToWrite, headers)
|
datasToWrite = append(datasToWrite, columnHeaders)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, record := range records {
|
for _, record := range records {
|
||||||
var row []string
|
var row []string
|
||||||
for _, header := range headers {
|
for _, h := range columnHeaders {
|
||||||
row = append(row, fmt.Sprintf("%v", record[header]))
|
row = append(row, fmt.Sprintf("%v", record[h]))
|
||||||
}
|
}
|
||||||
datasToWrite = append(datasToWrite, row)
|
datasToWrite = append(datasToWrite, row)
|
||||||
}
|
}
|
||||||
|
|
||||||
var sep rune
|
return WriteCsvFile(filepath, datasToWrite, appendToExistingFile, delimiter)
|
||||||
if len(delimiter) > 0 {
|
|
||||||
sep = delimiter[0]
|
|
||||||
} else {
|
|
||||||
sep = ','
|
|
||||||
}
|
|
||||||
|
|
||||||
return WriteCsvFile(filepath, datasToWrite, appendToExistingFile, sep)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if the value of map which to be written into csv is basic type.
|
// check if the value of map which to be written into csv is basic type.
|
||||||
@@ -814,8 +807,3 @@ func isCsvSupportedType(v interface{}) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// sort map by key in alphabeta order.
|
|
||||||
// func sortMap(records []map[string]any) []map[string]any {
|
|
||||||
|
|
||||||
// }
|
|
||||||
|
|||||||
@@ -339,7 +339,8 @@ func ExampleWriteMapsToCsv() {
|
|||||||
{"Name": "Jim", "Age": "21", "Gender": "male"},
|
{"Name": "Jim", "Age": "21", "Gender": "male"},
|
||||||
}
|
}
|
||||||
|
|
||||||
err := WriteMapsToCsv(csvFilePath, records, false, ';')
|
headers := []string{"Name", "Age", "Gender"}
|
||||||
|
err := WriteMapsToCsv(csvFilePath, records, false, ';', headers)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
@@ -350,7 +351,7 @@ func ExampleWriteMapsToCsv() {
|
|||||||
fmt.Println(content)
|
fmt.Println(content)
|
||||||
|
|
||||||
// Output:
|
// Output:
|
||||||
// [[Age Gender Name] [22 female Lili] [21 male Jim]]
|
// [[Name Age Gender] [Lili 22 female] [Jim 21 male]]
|
||||||
}
|
}
|
||||||
|
|
||||||
func ExampleWriteStringToFile() {
|
func ExampleWriteStringToFile() {
|
||||||
|
|||||||
@@ -397,7 +397,8 @@ func TestWriteMapsToCsv(t *testing.T) {
|
|||||||
{"Name": "Jim", "Age": "21", "Gender": "male"},
|
{"Name": "Jim", "Age": "21", "Gender": "male"},
|
||||||
}
|
}
|
||||||
|
|
||||||
err := WriteMapsToCsv(csvFilePath, records, false, ';')
|
headers := []string{"Name", "Age", "Gender"}
|
||||||
|
err := WriteMapsToCsv(csvFilePath, records, false, ';', headers)
|
||||||
|
|
||||||
assert.IsNil(err)
|
assert.IsNil(err)
|
||||||
|
|
||||||
@@ -407,9 +408,9 @@ func TestWriteMapsToCsv(t *testing.T) {
|
|||||||
|
|
||||||
assert.Equal(3, len(content))
|
assert.Equal(3, len(content))
|
||||||
assert.Equal(3, len(content[0]))
|
assert.Equal(3, len(content[0]))
|
||||||
assert.Equal("22", content[1][0])
|
assert.Equal("Lili", content[1][0])
|
||||||
assert.Equal("female", content[1][1])
|
assert.Equal("22", content[1][1])
|
||||||
assert.Equal("Lili", content[1][2])
|
assert.Equal("female", content[1][2])
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestWriteStringToFile(t *testing.T) {
|
func TestWriteStringToFile(t *testing.T) {
|
||||||
|
|||||||
6
fileutil/testdata/test3.csv
vendored
6
fileutil/testdata/test3.csv
vendored
@@ -1,3 +1,3 @@
|
|||||||
Age;Gender;Name
|
Name;Age;Gender
|
||||||
22;female;Lili
|
Lili;22;female
|
||||||
21;male;Jim
|
Jim;21;male
|
||||||
|
|||||||
|
6
fileutil/testdata/test4.csv
vendored
6
fileutil/testdata/test4.csv
vendored
@@ -1,3 +1,3 @@
|
|||||||
Age;Gender;Name
|
Name;Age;Gender
|
||||||
22;female;Lili
|
Lili;22;female
|
||||||
21;male;Jim
|
Jim;21;male
|
||||||
|
|||||||
|
Reference in New Issue
Block a user