gwydion93
gwydion93

Reputation: 1923

Coffeescript syntax issue with for statement

Using Coffeescript, I am trying to set conditionals for setting a fillColor on a graph plot for two variables; lastVisibility and curr_visibility. Something is not right with my syntax. Any suggestions

for set in datasets
            line.push
                data: set,
                lines:
                    show: true
                    fill: true
                    opacity: 0.7
                    fillColor: if lastVisibilty == 0 & curr_visibility == 0 
                        then "#C90E30"
                    else lastVisibilty == 0 & curr_visibility == 1
                        then "#439C32"
                    else lastVisibilty == 1 & curr_visibility == 0
                        then "#C90E30"
                    else
                        "#439C32"

Upvotes: 2

Views: 45

Answers (1)

mu is too short
mu is too short

Reputation: 434965

There are lots of problems here:

  1. You only use then when you're using a one-liner such as a = if b then c else d, if you're using the multi-line form of if then you don't use thens.
  2. You have multiple else branches where you mean else if.
  3. & and && are different things, & is a bit-wise operator, && is the logical conjunction you're looking for.
  4. You need to be very careful and consistent with your indentation.

Applying those adjustments to your code you get:

for set in datasets
    line.push
        data: set,
        lines:
            show: true
            fill: true
            opacity: 0.7
            fillColor: if lastVisibilty == 0 && curr_visibility == 0 
                "#C90E30"
            else if lastVisibilty == 0 && curr_visibility == 1
                "#439C32"
            else if lastVisibilty == 1 && curr_visibility == 0
                "#C90E30"
            else
                "#439C32"

However, the conditional logic inside your loop doesn't depend on set (i.e. is loop invariant) so you should factor that out:

fillColor = if lastVisibilty == 0 && curr_visibility == 0 
        "#C90E30"
    else if lastVisibilty == 0 && curr_visibility == 1
        "#439C32"
    else if lastVisibilty == 1 && curr_visibility == 0
        "#C90E30"
    else
        "#439C32"
for set in datasets
    line.push
        data: set,
        lines:
            show: true
            fill: true
            opacity: 0.7
            fillColor: fillColor

Or better, push all the invariant stuff outside the loop to further clarify the code:

fillColor = if lastVisibilty == 0 && curr_visibility == 0 
        "#C90E30"
    else if lastVisibilty == 0 && curr_visibility == 1
        "#439C32"
    else if lastVisibilty == 1 && curr_visibility == 0
        "#C90E30"
    else
        "#439C32"
lines =
    show: true
    fill: true
    opacity: 0.7
    fillColor: fillColor
for set in datasets
    line.push
        data: set,
        lines: lines

Or, since a for-loop is an expression, you could say:

fillColor = if lastVisibilty == 0 && curr_visibility == 0 
        "#C90E30"
    else if lastVisibilty == 0 && curr_visibility == 1
        "#439C32"
    else if lastVisibilty == 1 && curr_visibility == 0
        "#C90E30"
    else
        "#439C32"
lines =
    show: true
    fill: true
    opacity: 0.7
    fillColor: fillColor
line = ({ data: set, lines: line } for set in datasets)

Assuming that line is empty before your loop of course; if it isn't then you could use Array.prototype.concat:

line = line.concat({data: set, lines: line } for set in datasets)

to append the loop's data to line.

Upvotes: 2

Related Questions