首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何将CSV文件重新排序为按特定列的内容分组

如何将CSV文件重新排序为按特定列的内容分组
EN

Stack Overflow用户
提问于 2022-07-29 19:10:59
回答 2查看 139关注 0票数 2

我是新来的go Golang,我的问题也没有被澄清,但这是我正在努力实现的。我有一个csv文件,如下所示,因为我主要尝试重新安排/排序上一列(status=passed,failed/sort)

代码语言:javascript
运行
复制
test,test-cat,skipped
test,test-cat,failed
test,test-cat,passed
test,test-cat,skipped
test,test-cat,passed
test,test-cat,failed

如果具有相同的状态,则期望最后一列将它们分组在一起。

代码语言:javascript
运行
复制
test,test-cat,skipped
test,test-cat,skipped
test,test-cat,failed
test,test-cat,failed
test,test-cat,passed
test,test-cat,passed

用我做的这些代码,它看起来不太好:-)但是它可以按照我的意愿工作。

代码语言:javascript
运行
复制
package main
import (
        "bufio"
        "fmt"
        "os"
        "strings"
)
func main() {
        var FailStat, SkipStat,PassStat []string
      
        file, err := os.Open("test.csv")

        if err != nil {
                fmt.Println(err)
        } else {
                scanner := bufio.NewScanner(file)
                for scanner.Scan() {
                        line := scanner.Text()
                        if strings.Contains(line, "failed") {
                                FailStat = append(FailStat, line)

                        }
                        if strings.Contains(line, "skipped") {
                                SkipStat = append(SkipStat, line)

                        }
                        if strings.Contains(line, "passed") {
                                PassStat = append(PassStat, line)

                        }                       
                }
        }
        file.Close()

        var finalstat []string
        finalstat = append(SkipStat, FailStat...)
        finalstat = append(finalstat, PassStat...)

        for _, line := range finalstat {
           fmt.Println(line)
   }
}

测试-运行:

代码语言:javascript
运行
复制
$ ./readfile 
test,test-cat,skipped
test,test-cat,skipped
test,test-cat,failed
test,test-cat,failed
test,test-cat,passed
test,test-cat,passed

一定有很多更好的方法,请指点。对新手的问题很抱歉!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-07-29 21:55:38

如果状态分组的顺序不重要(由于map的设计,您永远不应该期望从run到run得到相同的组排序),则依尼安的解决方案将有效。

如果您需要一致排序的组,则实际上是排序的:

代码语言:javascript
运行
复制
package main

import (
    "encoding/csv"
    "io"
    "log"
    "os"
    "sort"
    "strings"
)

type Row struct {
    Name, Category, Status string
}

func main() {
    in := `test,test-cat,skipped
test,test-cat,failed
test,test-cat,passed
test,test-cat,skipped
test,test-cat,passed
test,test-cat,failed
`
    r := csv.NewReader(strings.NewReader(in))

    rows := make([]Row, 0)
    for {
        record, err := r.Read()
        if err == io.EOF {
            break
        }
        if err != nil {
            log.Fatal(err)
        }
        row := Row{record[0], record[1], record[2]}
        rows = append(rows, row)
    }

    sort.Slice(rows, func(i, j int) bool { return rows[i].Status < rows[j].Status })

    w := csv.NewWriter(os.Stdout)

    for _, row := range rows {
        w.Write([]string{row.Name, row.Category, row.Status})
    }
    w.Flush()

    if err := w.Error(); err != nil {
        log.Fatal(err)
    }
}

我们得到:

代码语言:javascript
运行
复制
test,test-cat,failed
test,test-cat,failed
test,test-cat,passed
test,test-cat,passed
test,test-cat,skipped
test,test-cat,skipped

将sort.Slice的匿名函数中的< to >更改为反转排序顺序。

围棋游乐场

如果不想处理行结构,并在[]行和字符串之间进行转换:

代码语言:javascript
运行
复制
// ...
rows := make([][]string, 0)
for {
    row, err := r.Read()
    // ...
    rows = append(rows, row)
}

sort.Slice(rows, func(i, j int) bool { return rows[i][2] < rows[j][2] })

w := csv.NewWriter(os.Stdout)

for _, row := range rows {
    w.Write(row)
}
// ...

围棋游乐场

在一条评论中,你提到想要小组的特定顺序,现在我可以从你的原始代码中看到你的目标是什么。

在这种情况下,伊安安的解决方案是正确的:

代码语言:javascript
运行
复制
    // ...

    recordGroups := make(map[string][][]string)
    for {
        records, err := r.Read()
        if err == io.EOF {
            break
        }
        if err != nil {
            log.Fatal(err)
        }
        groupName := records[2]
        recordGroups[groupName] = append(recordGroups[groupName], records)
    }
    w := csv.NewWriter(os.Stdout)

    // Control the order with this slice of group names
    groupNames := []string{"failed", "passed", "skipped", "Bogus group!"}

    for _, groupName := range groupNames {
        recordGroup, ok := recordGroups[groupName]
        if !ok {
            log.Printf("did not find expected group %q\n", groupName)
            continue
        }
        for _, record := range recordGroup {
            if err := w.Write(record); err != nil {
                log.Fatalln("error writing record to csv:", err)
            }
        }
    }

    // ...
代码语言:javascript
运行
复制
2009/11/10 23:00:00 did not find expected group "Bogus group!"
test,test-cat,failed
test,test-cat,failed
test,test-cat,skipped
test,test-cat,skipped
test,test-cat,passed
test,test-cat,passed

围棋游乐场

票数 2
EN

Stack Overflow用户

发布于 2022-07-29 19:42:41

为此,最好使用标准库中提供的csv封装。这个逻辑涉及到创建一个字符串映射到一个字符串片段,其中键将是您想要分组的列,值是它唯一的行列表。

一旦填充了地图,接下来的操作将是以CSV格式打印结果。下面的示例涉及从变量中读取输入并将其打印回stdout。您可以引用包中的其他方法来对文本文件执行相同的操作。

代码语言:javascript
运行
复制
package main

import (
    "encoding/csv"
    "io"
    "log"
    "os"
    "strings"
)

func main() {
    in := `test,test-cat,skipped
test,test-cat,failed
test,test-cat,passed
test,test-cat,skipped
test,test-cat,passed
test,test-cat,failed
`
    r := csv.NewReader(strings.NewReader(in))
    dictMap := make(map[string][][]string)
    for {
        records, err := r.Read()
        if err == io.EOF {
            break
        }
        if err != nil {
            log.Fatal(err)
        }
        dictMap[records[2]] = append(dictMap[records[2]], records)
    }

    w := csv.NewWriter(os.Stdout)

    for _, records := range dictMap {
        for idx := range records {
            if err := w.Write(records[idx]); err != nil {
                log.Fatalln("error writing record to csv:", err)
            }
        }
    }

    w.Flush()

    if err := w.Error(); err != nil {
        log.Fatal(err)
    }
}

去操场

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73170034

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档