FAQ
Hello,

I am looking for feedback for an additional api for encoding/csv.

Example:

type CSVStrategy func(string, CSVRow)


type Foo struct {
     name string
     date Date
     number int
}


interface CSVParsable {
    func CSVStrategies() map[string]CSVStrategy
}


type CSVRow struct {
     header *map[string]int
     row []string
}


func (r *CSVRow) At(i int) string {
     return r.row[i]
}


func (r *CSVRow) Fetch(name string) string {
     return r.row[r.header[name]]
}


func (f *Foo) CSVStrategies() map[string]CSVStrategy {
     strategies := map[string]CSVStrategy {
       "name": func(field string, r CSVRow) {
           f.name = field
        },

       "date": func(field string, r CSVRow) {
           d := r.Fetch("date")
           if d == nil {
              d = r.Fetch("adjusted_date")
           }
           f.date = date.Parse(d)
        },
       "date": func(field string, r CSVRow) {
           f.date = int.Parse(field)
        },
      }
      return strategies
}

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Search Discussions

  • Paul Borman at Jul 17, 2015 at 1:26 am
    Can you provide some context and what problem you are solving? It looks
    like this is something that can be completely implemented outside the csv
    package. Why not have an external package do this?

         -Paul
    On Thu, Jul 16, 2015 at 4:06 PM, wrote:

    Hello,

    I am looking for feedback for an additional api for encoding/csv.

    Example:

    type CSVStrategy func(string, CSVRow)


    type Foo struct {
    name string
    date Date
    number int
    }


    interface CSVParsable {
    func CSVStrategies() map[string]CSVStrategy
    }


    type CSVRow struct {
    header *map[string]int
    row []string
    }


    func (r *CSVRow) At(i int) string {
    return r.row[i]
    }


    func (r *CSVRow) Fetch(name string) string {
    return r.row[r.header[name]]
    }


    func (f *Foo) CSVStrategies() map[string]CSVStrategy {
    strategies := map[string]CSVStrategy {
    "name": func(field string, r CSVRow) {
    f.name = field
    },

    "date": func(field string, r CSVRow) {
    d := r.Fetch("date")
    if d == nil {
    d = r.Fetch("adjusted_date")
    }
    f.date = date.Parse(d)
    },
    "date": func(field string, r CSVRow) {
    f.date = int.Parse(field)
    },
    }
    return strategies
    }

    --
    You received this message because you are subscribed to the Google Groups
    "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an
    email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • John McConnell at Jul 17, 2015 at 1:57 am
    Hello Paul,

    I thought about this design when I was creating code to convert a CSV file
    into a list of objects. I noticed I was doing a lot of duplication. Putting
    it into a separate package is fine. I think there is at least one strength
    of having it in the core library:

    In order to convert a row in a CSV file to an struct, a developer will only
    need to define one method. Also, this method will only have one
    responsibility (csv decoding). I guess I should have added to this to code.

    Parse(os []CSVParsable, csv [][]string) {
       i, row := range csv {
         if i == 0 {
           header := // convert to header
           continue
         }
         csvr := CSVRow{header, row}
         o := os[i - 1] // minus one because we don't include the header

         strategies := o.ParseStrategies()
         for field, parseField := range strategies {
           o.parseField(field, csvr)
         }
       }
    }


    On Thursday, July 16, 2015 at 6:41:51 PM UTC-5, John McConnell wrote:

    Hello,

    I am looking for feedback for an additional api for encoding/csv.

    Example:

    type CSVStrategy func(string, CSVRow)


    type Foo struct {
    name string
    date Date
    number int
    }


    interface CSVParsable {
    func CSVStrategies() map[string]CSVStrategy
    }


    type CSVRow struct {
    header *map[string]int
    row []string
    }


    func (r *CSVRow) At(i int) string {
    return r.row[i]
    }


    func (r *CSVRow) Fetch(name string) string {
    return r.row[r.header[name]]
    }


    func (f *Foo) CSVStrategies() map[string]CSVStrategy {
    strategies := map[string]CSVStrategy {
    "name": func(field string, r CSVRow) {
    f.name = field
    },

    "date": func(field string, r CSVRow) {
    d := r.Fetch("date")
    if d == nil {
    d = r.Fetch("adjusted_date")
    }
    f.date = date.Parse(d)
    },
    "date": func(field string, r CSVRow) {
    f.date = int.Parse(field)
    },
    }
    return strategies
    }
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Paul Borman at Jul 17, 2015 at 1:22 pm
    Another option to this is to use struct tags. It is a bit more code than
    what you have above, but it is probably easier to use. Essentially, you
    put the name of the column in the struct tag and then build up the column
    indices once the first row has been read. You can use the type of the
    field to determine how to decode the value. Essentially, this is building
    up your "strategies" just from struct tags. For unknown types you would
    still need to write your parse function and then simply register it, or you
    could just use the existing unmarshaller mechanism used in other encodings.

         -Paul
    On Thu, Jul 16, 2015 at 6:57 PM, John McConnell wrote:

    Hello Paul,

    I thought about this design when I was creating code to convert a CSV file
    into a list of objects. I noticed I was doing a lot of duplication. Putting
    it into a separate package is fine. I think there is at least one strength
    of having it in the core library:

    In order to convert a row in a CSV file to an struct, a developer will
    only need to define one method. Also, this method will only have one
    responsibility (csv decoding). I guess I should have added to this to code.

    Parse(os []CSVParsable, csv [][]string) {
    i, row := range csv {
    if i == 0 {
    header := // convert to header
    continue
    }
    csvr := CSVRow{header, row}
    o := os[i - 1] // minus one because we don't include the header

    strategies := o.ParseStrategies()
    for field, parseField := range strategies {
    o.parseField(field, csvr)
    }
    }
    }


    On Thursday, July 16, 2015 at 6:41:51 PM UTC-5, John McConnell wrote:

    Hello,

    I am looking for feedback for an additional api for encoding/csv.

    Example:

    type CSVStrategy func(string, CSVRow)


    type Foo struct {
    name string
    date Date
    number int
    }


    interface CSVParsable {
    func CSVStrategies() map[string]CSVStrategy
    }


    type CSVRow struct {
    header *map[string]int
    row []string
    }


    func (r *CSVRow) At(i int) string {
    return r.row[i]
    }


    func (r *CSVRow) Fetch(name string) string {
    return r.row[r.header[name]]
    }


    func (f *Foo) CSVStrategies() map[string]CSVStrategy {
    strategies := map[string]CSVStrategy {
    "name": func(field string, r CSVRow) {
    f.name = field
    },

    "date": func(field string, r CSVRow) {
    d := r.Fetch("date")
    if d == nil {
    d = r.Fetch("adjusted_date")
    }
    f.date = date.Parse(d)
    },
    "date": func(field string, r CSVRow) {
    f.date = int.Parse(field)
    },
    }
    return strategies
    }

    --
    You received this message because you are subscribed to the Google Groups
    "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an
    email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • John McConnell at Jul 17, 2015 at 1:45 pm
    Yes, I like this approach as well. It is using tags so it will be similar
    to the JSON api, which is a nice plus.
    On Friday, July 17, 2015 at 8:22:52 AM UTC-5, Paul Borman wrote:

    Another option to this is to use struct tags. It is a bit more code than
    what you have above, but it is probably easier to use. Essentially, you
    put the name of the column in the struct tag and then build up the column
    indices once the first row has been read. You can use the type of the
    field to determine how to decode the value. Essentially, this is building
    up your "strategies" just from struct tags. For unknown types you would
    still need to write your parse function and then simply register it, or you
    could just use the existing unmarshaller mechanism used in other encodings.

    -Paul

    On Thu, Jul 16, 2015 at 6:57 PM, John McConnell <johnnyi...@gmail.com
    <javascript:>> wrote:
    Hello Paul,

    I thought about this design when I was creating code to convert a CSV
    file into a list of objects. I noticed I was doing a lot of duplication.
    Putting it into a separate package is fine. I think there is at least one
    strength of having it in the core library:

    In order to convert a row in a CSV file to an struct, a developer will
    only need to define one method. Also, this method will only have one
    responsibility (csv decoding). I guess I should have added to this to code.

    Parse(os []CSVParsable, csv [][]string) {
    i, row := range csv {
    if i == 0 {
    header := // convert to header
    continue
    }
    csvr := CSVRow{header, row}
    o := os[i - 1] // minus one because we don't include the header

    strategies := o.ParseStrategies()
    for field, parseField := range strategies {
    o.parseField(field, csvr)
    }
    }
    }


    On Thursday, July 16, 2015 at 6:41:51 PM UTC-5, John McConnell wrote:

    Hello,

    I am looking for feedback for an additional api for encoding/csv.

    Example:

    type CSVStrategy func(string, CSVRow)


    type Foo struct {
    name string
    date Date
    number int
    }


    interface CSVParsable {
    func CSVStrategies() map[string]CSVStrategy
    }


    type CSVRow struct {
    header *map[string]int
    row []string
    }


    func (r *CSVRow) At(i int) string {
    return r.row[i]
    }


    func (r *CSVRow) Fetch(name string) string {
    return r.row[r.header[name]]
    }


    func (f *Foo) CSVStrategies() map[string]CSVStrategy {
    strategies := map[string]CSVStrategy {
    "name": func(field string, r CSVRow) {
    f.name = field
    },

    "date": func(field string, r CSVRow) {
    d := r.Fetch("date")
    if d == nil {
    d = r.Fetch("adjusted_date")
    }
    f.date = date.Parse(d)
    },
    "date": func(field string, r CSVRow) {
    f.date = int.Parse(field)
    },
    }
    return strategies
    }

    --
    You received this message because you are subscribed to the Google Groups
    "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an
    email to golang-nuts...@googlegroups.com <javascript:>.
    For more options, visit https://groups.google.com/d/optout.
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-nuts @
categoriesgo
postedJul 16, '15 at 11:41p
activeJul 17, '15 at 1:45p
posts5
users2
websitegolang.org

2 users in discussion

John McConnell: 3 posts Paul Borman: 2 posts

People

Translate

site design / logo © 2022 Grokbase