1
\$\begingroup\$

This code works, but it's so ugly, so I was hesitant to put it on display. There must be a nicer/easier way to achieve this. The main issue is to count each unique occurrence during runtime when the object creation takes time.

Input:

1190 W X 1648 H X 14 T
S
1190 W X 1254 H X 14 T
S
1190 W X 1254 H X 14 T
S
1190 W X 1254 H X 14 T
S
1190 W X 1254 H X 14 T
S
1190 W X 1648 H X 14 T

I read each word by word, I need to extract from this data, occurrences, plus number of times each elements occurs.

func CreateGlassBoxNew(db *gorm.DB, boxID uint, internalName string, glassBoxData []byte) {
    m := make(map[string]Measurement)
    var outerList []string
    var innerList []int
    var index = 0
    var count = 0
    var appendStr string
    scanner := bufio.NewScanner(strings.NewReader(string(glassBoxData)))
    scanner.Split(bufio.ScanWords)
    for scanner.Scan() {
        if scanner.Text() == "S" || scanner.Text() == "W" || scanner.Text() == "H" || scanner.Text() == "T" || scanner.Text() == "X" {
            continue
        }

        appendStr += scanner.Text() + "-"
        innerList = append(innerList, addMeasurementInt(scanner.Text()))

        index++
        if index == 3 {
            dump.P(innerList)
            count++
            fmt.Println(count)
            m[appendStr] = Measurement{
                Width:      innerList[0],
                Height:     innerList[1],
                Thicknes:   innerList[2],
                Quantity:   count,
                GlassBoxID: boxID,
            }
            innerList = nil
            outerList = append(outerList, appendStr)

            appendStr = ""
            index = 0

        }
    }
    if err := scanner.Err(); err != nil {
        dump.P(err)
    }

    dump.P(m)

    occurenceMap := CountOccurence(outerList)

    var finalList []Measurement
    for key, element := range m {
        finalList = append(finalList, Measurement{
            Width:      element.Width,
            Height:     element.Height,
            Thicknes:   element.Thicknes,
            Quantity:   occurenceMap[key],
            GlassBoxID: boxID,
        })
    }
    dump.P(finalList)
}

the final result ready for db insert, looks like this, here is the quantity variable set.

[]models.Measurement [ #len=2
  models.Measurement {
    Width: int(1190),
    Height: int(1648),
    Thicknes: int(14),
    Quantity: int(2),
    GlassBoxID: uint(3436),
    BluePrintName: *string<nil>,
  },
  models.Measurement {
    Width: int(1190),
    Height: int(1254),
    Thicknes: int(14),
    Quantity: int(4),
    GlassBoxID: uint(3436),
    BluePrintName: *string<nil>,
  },
],
\$\endgroup\$

1 Answer 1

3
\$\begingroup\$

I think this can be simplified greatly be leveraging the fact that your input data:

  1. Is coming all at once (is a []byte not a io.Reader)
  2. At least appears very structured

I am thinking that the who scanner loop can bet replaced by:

glassBoxes := strings.Split(string(glassBoxData), "\nS\n")

    for i := range glassBoxes {
        vals := strings.Split(glassBoxes[i], " ")
        if len(vals) != 8 {
            log.Fatal("invalid row: " + glassBoxes[i])
        }
        width, err := strconv.Atoi(vals[0])
        if err != nil {
            log.Fatal("bad width " + err.Error())
        }
        height, err := strconv.Atoi(vals[3])
        if err != nil {
            log.Fatal("bad height " + err.Error())
        }
        thickness, err := strconv.Atoi(vals[6])
        if err != nil {
            log.Fatal("bad thickness " + err.Error())
        }
        quantity := i + 1

        //construct you `Measurement` here and load it into 
        // the collecting slice
        fmt.Printf("w: %d h: %d t: %d count: %d\n", width, height, thickness, quantity)
    }
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.