如果我有一个 csv 读入一个结构,我该如何操作输入来构建我想要的结构?在各种教程之后,我陷入了困境。这是我离得最近的一次。
我基本上想打开一个 csv,读取选定的列,确保在引用该列时从同一行记录值。然后以可以放入数据库的格式生成数据。
示例 CSV:
Ignore,Customer,Fruit,Number
123,A,Apple,1
123,A,Apple,3
123,B,Orange,4
123,C,Melon,5
示例代码:
package main
import (
"bufio"
"encoding/csv"
"encoding/json"
"fmt"
"io"
"log"
"os"
)
type Account struct {
Customer string `json:"Customer"`
LineItem *LineItem `json:"LineItem"`
}
type LineItem struct {
ProductName string `json:"ProductName"`
Count string `json:"Count"`
}
func main() {
csvFile, _ := os.Open("/home/frank/gocode/src/local/billing/fruit.csv")
reader := csv.NewReader(bufio.NewReader(csvFile))
var billData []Account
for {
line, error := reader.Read()
if error == io.EOF {
break
} else if error != nil {
log.Fatal(error)
}
billData = append(billData, Account{
Customer: line[1],
LineItem: &LineItem{
ProductName: line[2],
Count: line[3],
},
})
}
billingJson, _ := json.Marshal(billData)
fmt.Println(string(billingJson))
}
当前输出为:
[{"Customer":"Customer","LineItem":{"ProductName":"Fruit","Count":"Number"}},{"Customer":"A","LineItem":{"ProductName":"Apple","Count":"1"}},{"Customer":"A","LineItem":{"ProductName":"Apple","Count":"3"}},{"Customer":"B","LineItem":{"ProductName":"Orange","Count":"4"}},{"Customer":"C","LineItem":{"ProductName":"Melon","Count":"5"}}]
我想去掉第一条记录,这样标题就不会保留了。例如
[{"Customer":"A","LineItem":{"ProductName":"Apple","Count":"1"}},{"Customer":"A","LineItem":{"ProductName":"Apple","Count":"3"}},{"Customer":"B","LineItem":{"ProductName":"Orange","Count":"4"}},{"Customer":"C","LineItem":{"ProductName":"Melon","Count":"5"}}]
合并,使客户 A 成为包含两个 LineItem 的一条记录,例如
[{"Customer":"A","LineItem":{"ProductName":"Apple","Count":"1"},"LineItem":{"ProductName":"Apple","Count":"3"}},{"Customer":"B","LineItem":{"ProductName":"Orange","Count":"4"}},{"Customer":"C","LineItem":{"ProductName":"Melon","Count":"5"}}]
任何最佳实践 - 欢迎使用替代方法(不确定此处的 map 是否更好)。希望有足够的信息来帮助我。
最佳答案
删除第一个条目就像 billData = billData[1:] 一样简单。那,或者进行初始读取以提取列名称。
在第二部分,您当前的数据结构不能容忍一对多关系(每个帐户只有一个 LineItem)。之后您需要对列表进行一些处理。 CSV 文件必须是 1:1,因为每一行都被视为一个独立的记录。最简单的方法是使用映射使其成为一对多,但您也可以简单地遍历 slice (保留更接近现有代码):
https://play.golang.org/p/3uevo0taKR5
package main
import (
"bytes"
"encoding/csv"
"encoding/json"
"fmt"
"io"
"log"
)
var data = `Ignore,Customer,Fruit,Number
123,A,Apple,1
123,A,Apple,3
123,B,Orange,4
123,C,Melon,5`
type Account struct {
Customer string `json:"Customer"`
LineItems []LineItem `json:"LineItems"`
}
type LineItem struct {
ProductName string `json:"ProductName"`
Count string `json:"Count"`
}
func main() {
reader := csv.NewReader(bytes.NewBufferString(data))
// Read column label data and discard
if _, err := reader.Read(); err != nil {
log.Fatal(err)
}
var billData []Account
for {
line, err := reader.Read()
if err == io.EOF {
break
}
if err != nil {
log.Fatal(err)
}
found := false
for i := range billData {
if billData[i].Customer == line[1] {
found = true
billData[i].LineItems = append(billData[i].LineItems, LineItem{
ProductName: line[2],
Count: line[3],
})
break
}
}
if !found {
billData = append(billData, Account{
Customer: line[1],
LineItems: []LineItem{
{
ProductName: line[2],
Count: line[3],
},
},
})
}
}
billingJson, err := json.MarshalIndent(billData, "", " ")
if err != nil {
log.Fatal(err)
}
fmt.Println(string(billingJson))
}
输出:
[
{
"Customer": "A",
"LineItems": [
{
"ProductName": "Apple",
"Count": "1"
},
{
"ProductName": "Apple",
"Count": "3"
}
]
},
{
"Customer": "B",
"LineItems": [
{
"ProductName": "Orange",
"Count": "4"
}
]
},
{
"Customer": "C",
"LineItems": [
{
"ProductName": "Melon",
"Count": "5"
}
]
}
]
最后,我建议使用 err 或类似的错误变量。 error 是内置错误类型的名称,因此通过命名您的变量,您将隐藏该类型并使其无法在同一范围内声明该类型的变量。虽然这不会影响您当前的代码,但它仍然是一种非常糟糕的做法,最终可能会给您带来麻烦。
关于json - CSV 到结构建议,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48890994/
我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h
我正在使用ruby1.9解析以下带有MacRoman字符的csv文件#encoding:ISO-8859-1#csv_parse.csvName,main-dialogue"Marceu","Giveittohimóhe,hiswife."我做了以下解析。require'csv'input_string=File.read("../csv_parse.rb").force_encoding("ISO-8859-1").encode("UTF-8")#=>"Name,main-dialogue\r\n\"Marceu\",\"Giveittohim\x97he,hiswife.\"\
查看Ruby的CSV库的文档,我非常确定这是可能且简单的。我只需要使用Ruby删除CSV文件的前三列,但我没有成功运行它。 最佳答案 csv_table=CSV.read(file_path_in,:headers=>true)csv_table.delete("header_name")csv_table.to_csv#=>ThenewCSVinstringformat检查CSV::Table文档:http://ruby-doc.org/stdlib-1.9.2/libdoc/csv/rdoc/CSV/Table.html
在我的Controller中,我通过以下方式在我的index方法中支持HTML和JSON:respond_todo|format|format.htmlformat.json{renderjson:@user}end在浏览器中拉起它时,它会自然地以HTML呈现。但是,当我对/user资源进行内容类型为application/json的curl调用时(因为它是索引方法),我仍然将HTML作为响应。如何获取JSON作为响应?我还需要说明什么? 最佳答案 您应该将.json附加到请求的url,提供的格式在routes.rb的路径中定义。这
CSV.open(name,"r").eachdo|row|putsrowend我得到以下错误:CSV::MalformedCSVErrorUnquotedfieldsdonotallow\ror\n文件名是一个.txt制表符分隔文件。我是专门做的。我有一个.csv文件,我转到excel,并将文件保存为.txt制表符分隔的文件。所以它是制表符分隔的。CSV.open不应该能够读取制表符分隔的文件吗? 最佳答案 尝试像这样指定字段分隔符:CSV.open("name","r",{:col_sep=>"\t"}).eachdo|row|
给定一个复杂的对象层次结构,幸运的是它不包含循环引用,我如何实现支持各种格式的序列化?我不是来讨论实际实现的。相反,我正在寻找可能会派上用场的设计模式提示。更准确地说:我正在使用Ruby,我想解析XML和JSON数据以构建复杂的对象层次结构。此外,应该可以将该层次结构序列化为JSON、XML和可能的HTML。我可以为此使用Builder模式吗?在任何提到的情况下,我都有某种结构化数据-无论是在内存中还是文本中-我想用它来构建其他东西。我认为将序列化逻辑与实际业务逻辑分开会很好,这样我以后就可以轻松支持多种XML格式。 最佳答案 我最
我有一个非常简单的RubyRack服务器,例如:app=Proc.newdo|env|req=Rack::Request.new(env).paramspreq.inspect[200,{'Content-Type'=>'text/plain'},['Somebody']]endRack::Handler::Thin.run(app,:Port=>4001,:threaded=>true)每当我使用JSON对象向服务器发送POSTHTTP请求时:{"session":{"accountId":String,"callId":String,"from":Object,"headers":
我正在尝试将一个简单的CSV文件读入HTML表格以在浏览器中显示,但我遇到了麻烦。这就是我正在尝试的:Controller:defshow@csv=CSV.open("file.csv",:headers=>true)end查看:输出:NameStartDateEndDateQuantityPostalCode基本上我只获取标题,而不会读取和呈现CSV正文。 最佳答案 这最终成为最终解决方案:Controller:defshow#OpenaCSVfile,andthenreaditintoaCSV::Tableobjectforda
Region是HBase数据管理的基本单位,region有一点像关系型数据的分区。region中存储这用户的真实数据,而为了管理这些数据,HBase使用了RegionSever来管理region。Region的结构hbaseregion的大小设置默认情况下,每个Table起初只有一个Region,随着数据的不断写入,Region会自动进行拆分。刚拆分时,两个子Region都位于当前的RegionServer,但处于负载均衡的考虑,HMaster有可能会将某个Region转移给其他的RegionServer。RegionSplit时机:当1个region中的某个Store下所有StoreFile
您将如何构建一个简单的Sinatra应用程序?我正在制作,我希望该应用具有以下功能:“应用程序”更像是一个包含所有信息的管理仪表板。然后另一个应用程序将通过REST访问信息。我还没有创建仪表板,只是从数据库中获取东西session和身份验证(尚未实现)您可以上传图片,其他应用可以显示这些图片我已经使用RSpec创建了一个测试文件通过Prawn生成报告目前的设置是这样的:app.rbtest_app.rb因为我实际上只有应用程序和测试文件。到目前为止,我已经将Datamapper用于ORM,将SQLite用于数据库。这是我的第一个Ruby/Sinatra项目,所以欢迎任何和所有建议-我应