Should I use AND or OR when combining two negative conditions?

Issue

Three vehicle types are Car, Motorcycle and Bicycle. Three statuses are Available, Reserved and Sold.

I want to print the information of all vehicles that are not Car and are not Sold, i.e. sold cars should not be printed. In other words, print information of everything that is Motorcycle or Bicycle, with any status among Available, Reserved and Sold. If it is a Car, still print as long as it is Available or Reserved.

The vehicles are:

  1. Car – Sold
  2. Car – Available
  3. Car – Reserved
  4. Bicycle – Sold
  5. Bicycle – Available
  6. Bicycle – Reserved
  7. Motorcycle – Sold
  8. Motorcycle – Available
  9. Motorcycle – Reserved

I expect the following code to print everything except number 1 (Car – Sold)

My code:

for _, v := range results {
    if v.Type != "Car" && v.Status != "Sold" {  // && does not work but || works
        resp = append(resp, &VehicleInfo {
            ID: v.Id,
            Brand: v.Brand,
            Type: v.Type,
            Status: v.Sold,
        })
    }
}

fmt.Println(resp)

When I use AND (&&), Println result is very strange, it outputs 5, 6, 8, 9. However, when I switch to OR (||), it prints exactly what I want, which is everything except 1 (sold car), which is a list of all Motorcycle (any status), all Bicycle (any status) and all Car that is either Available or Reserved.

What is the problem here? I thought using AND (&&) was the right answer, but it is not.

Solution

Your problem statement is… unclear. The statement

I want to print the information of all vehicles that are not Car and are not Sold,…

But the remainder of the problem statement:

… i.e. sold cars should not be printed. In other words, print information of everything that is Motorcycle or Bicycle, with any status among Available, Reserved and Sold. If it is a Car, still print as long as it is Available or Reserved.

Indicates that you want to filter out (exclude) cars that have been sold.

The easiest way is something like this:

for _, v := range results {
  isSoldCar := v.Type == "Car" && v.Status == "Sold"

  if isSoldCar {
    continue
  }

  resp = append(resp, &VehicleInfo {
    ID: v.Id,
    Brand: v.Brand,
    Type: v.Type,
    Status: v.Sold,
  })

}

or this:

for _, v := range results {
  isSoldCar := v.Type == "Car" && v.Status == "Sold"

  if !isSoldCar {
    resp = append(resp, &VehicleInfo {
      ID: v.Id,
      Brand: v.Brand,
      Type: v.Type,
      Status: v.Sold,
    })
  }

}

Answered By – Nicholas Carey

Answer Checked By – Katrina (GoLangFix Volunteer)

Leave a Reply

Your email address will not be published.