Reputation: 939
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
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
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