首先,我是新来的,我正在努力学习Golang。我想检查我的csv文件(有三个值:类型、制造商、型号(并创建一个新的csv,在进行筛选操作后,我想将新数据(已筛选(写入创建的csv档案。这是我的代码,所以你可以更清楚地理解我。
package main
import (
"encoding/csv"
"fmt"
"os"
)
func main() {
//openning my csv file which is vehicles.csv
recordFile, err := os.Open("vehicles.csv")
if err != nil{
fmt.Println("An error encountered ::", err)
}
//reading it
reader := csv.NewReader(recordFile)
vehicles, _ := reader.ReadAll()
//creating a new csv file
newRecordFile, err := os.Create("newCsvFile.csv")
if err != nil{
fmt.Println("An error encountered ::", err)
}
//writing vehicles.csv into the new csv
writer := csv.NewWriter(newRecordFile)
err = writer.WriteAll(vehicles)
if err != nil {
fmt.Println("An error encountered ::", err)
}
}
在我构建它之后,它就是这样工作的。它读取所有数据并将其写入新创建的csv文件。但这里的问题是,我想过滤读取的csv的重复项,它是车辆,我正在创建另一个函数(主函数之外(来过滤重复项,但我做不到,因为汽车的类型是[][]string。我在互联网上搜索了关于过滤重复项的信息,但我找到的都是int或string类型。我想做的是创建一个函数,并在WriteAll操作之前调用它,这样WriteAll就可以将正确的(过滤后的重复数据(写入新的csv文件中。请帮帮我!!我很感激你的回答。编码快乐!
这取决于如何定义"唯一性";,但总的来说,这个问题有几个方面。
什么是独一无二的?
- 所有字段必须相等
- 只有某些字段必须相等
- 在比较之前规范化部分或所有字段
您有几种方法可以应用您的独特性,包括:
- 您可以使用一个由";碎片";唯一性,需要O(N(状态
- 您可以对记录进行排序,并在迭代时与之前的记录进行比较,这需要O(1(状态,但更复杂
过滤和输出有两种方法:
- 您可以使用循环在旧切片的基础上构建一个新切片,并一次写入所有切片,这需要O(N(空间
- 如果不需要排序,可以边写边将记录写入文件,这需要O(1(空间
我认为一个相当简单和高效的方法是从第一个、第二个和第三个中选择(1(,这看起来像:
package main
import (
"encoding/csv"
"errors"
"io"
"log"
"os"
)
func main() {
input, err := os.Open("vehicles.csv")
if err != nil {
log.Fatalf("opening input file: %s", err)
}
output, err := os.Create("vehicles_filtered.csv")
if err != nil {
log.Fatalf("creating output file: %s", err)
}
defer func() {
// Ensure the file is closed at the end of the program
if err := output.Close(); err != nil {
log.Fatalf("finalizing output file: %s", err)
}
}()
reader := csv.NewReader(input)
writer := csv.NewWriter(output)
seen := make(map[[3]string]bool)
for {
// Read in one record
record, err := reader.Read()
if errors.Is(err, io.EOF) {
break
}
if err != nil {
log.Fatalf("reading record: %s", err)
}
if len(record) != 3 {
log.Printf("bad record %q", record)
continue
}
// Check if the record has been seen before, skipping if so
key := [3]string{record[0], record[1], record[2]}
if seen[key] {
continue
}
seen[key] = true
// Write the record
if err := writer.Write(record); err != nil {
log.Fatalf("writing record %d: %s", len(seen), err)
}
}
}