maxflow
maxflow

Reputation: 939

How to check if int variable has been set?

Lets say I have a variable num.

Before I can evaluate an if statement, I need to check if this variable has been set in the first place. Typically I would use either -1, 0 or math.MaxInt32/math.MinInt32 but for this task I need to check if my program has set its value.

I tried nums := nil and in my if statement I had something like if nums == nil || ....

But when creating the nums variable I was surprised to get the error cannot convert nil to type int. How I can achieve what I want to do?

To make it clear: This is a leetcode question and don't have control of the inputs, they put all sorts of numbers inside include math.MaxInt32, math.MinInt32

Full code:

func thirdMax(nums []int) int {

    dict := make(map[int]int, 0)

    varmaxOne := math.MinInt32
    maxTwo := math.MinInt32
    maxThree := math.MinInt32


    for _, value := range nums {

        if value >= maxOne && dict[value] < 1 {

            maxThree = maxTwo
            maxTwo = maxOne
            maxOne = value

        }else if value >= maxTwo && dict[value] < 1{
            maxThree = maxTwo
            maxTwo = value
        } else if value >= maxThree && dict[value] < 1 {
            maxThree = value
        }

        dict[value] += 1
    }

    if maxThree == math.MinInt32 {
        return maxTwo
    }
    return maxThree

}

func max(a int, b int) int {
    if a > b {
        return a
    }
    return b
}

Test

func TestThirdMax(t *testing.T) {
    //array := []int{2, 3, -1, -9, 11, 4, 3, 0, -100}
    //array := []int{2, 2, 3, 1}
    array := []int{1,2,-2147483648}
    //array := []int{3,2,1}
    result := thirdMax(array)

    if result != 2 {
        t.Errorf("Expected 2, but it was %d instead.", array)
    }
}

The code above use math.MinInt32, but fails with the input given. The idea was to have nil instead and put a check in the if statement, but fails as stated above.

Upvotes: 7

Views: 31138

Answers (2)

eugenioy
eugenioy

Reputation: 12393

As stated in the comments, you cannot check if an int has been set or not.

And using math.MinInt32 as a signal value would fail if you get that in the input.

So if you want to implement it that way, the only option is to use pointers (*int).

With pointers, you are able to check if they were set because they start with a nil value as you expect.

However, the logic gets a bit more complex that you implemented as you need to work with pointers and references.

See below a possible implementation, trying to use the same logic you posted, only changing to use pointers.

Another option might be to just sort the array and work with the sorted elements to find the third one.

Playground link: https://play.golang.org/p/ro_NIrDEo_s

func thirdMax(nums []int) int {

    dict := make(map[int]int, 0)

    // these will start with "nil values"
    var maxOne *int
    var maxTwo *int
    var maxThree *int


    for _, value := range nums {

        if maxOne == nil || value >= *maxOne && dict[value] < 1 {

            maxThree = maxTwo
            maxTwo = maxOne
            maxOne = new(int)
            *maxOne = value

        }else if maxTwo == nil || value >= *maxTwo && dict[value] < 1{
            maxThree = maxTwo
            maxTwo = new(int)
            *maxTwo = value
        } else if maxThree == nil || value >= *maxThree && dict[value] < 1 {
            maxThree = new(int)
            *maxThree = value
        }

        dict[value] += 1
    }

    if maxOne == nil {
        panic("does not work with empty input array!")
    }
    if maxTwo == nil {
        return *maxOne
    }
    if maxThree == nil {
        return *maxTwo
    }
    return *maxThree

}

Upvotes: 9

trey-jones
trey-jones

Reputation: 3437

As the comments suggest, the Zero Value for all int types in Go is 0. If 0 is a possible value for a number, and you need to check if it has been assigned or not, then you will probably want to use a Struct type with some metadata attached, rather than the primitive type.

As usual for these sorts of questions, there are precedents for this in the standard library.

Take a look at the database/sql package's Null types. These types are also justified by implementing Scanner, but you can use the same idea any time you need to check whether a primitive value should truly be equal to Null, rather than it's zero value.

Upvotes: 13

Related Questions