1

I want to do this:

var arr = [0,1,0,1,0,2,1,0,0]

switch arr {
case [1,_,_,_,_,_,_,_]: print("Yay")

default: print("Nay")
}

But I get this error: "'_' can only appear in a pattern or on the left side of an assignment"

I searched around on this error message and "wildcards swift array switch statements" and it seems like it is not possible to use wildcards in this context, but there may be some sort of workaround using 'operator overloading' with something involving ~=. However, this is way over my current knowledge, I haven't found a case example exactly like mine, and there seems to be a fair amount of implied concern that operator overloading is bad for some reason. Also, the examples I've found that is sort of like my case look very convoluted. I'm a self-taught amateur just trying to hack together a basic app to make my work life easier, so apologies for any stupid questions but I'd like to better understand the following:

  1. Why can't I use wildcards in this context? It seems like they work with tuples but not arrays for some reason, and I don't get why one would work but not the other.

  2. Is operating overloading actually 'bad' and is there a relatively straightforward way to implement this functionality?

  3. If not- can someone recommend an alternate approach? I chose this approach because I have two arrays, one for a series of questions, one to record responses to each question. I want to implement pretty complicated logic where the configuration of responses to prior questions will determine which question is presented next (example below). I wasted a bunch of time drowning in convoluted 'if' statements before realizing I needed a cleaner approach and this seemed to be it. However, without wildcards or something similar, it would not be practical to explicitly define every case. Could someone recommend a different approach in this situation? Obviously, this is a streamlined example and there would be many more defined cases. Thanks in advance.

     var responseArr = [0,2,1,2,1,0,0] // 0 = unasked, 1 = asked answered no, 2 = asked answered yes
    
     switch responseArr {
       case: [0,_,_,2,1,0,_]: nextQuestion = questionArr[0] // If 'yes' to question 4, no to question 5, and questions 1 and 6 were not asked yet, ask question 1
       case: [1,_,_,2,1,0,_]: nextQuestion = questionArr[5] // If 'yes' to question 4, no to question 5, no to question 1, and question 6 was not asked yet, ask question 6
       ...
       default: print("error")
     }
    
Chinez
  • 551
  • 2
  • 6
  • 29
  • 1
    That’s a lot of questions at the same time. Here is some interesting reading regarding the first question [Types](https://docs.swift.org/swift-book/ReferenceManual/Types.html), [Patterns](https://docs.swift.org/swift-book/ReferenceManual/Patterns.html). One option for the 3rd question is to make a tuple out of the array, see [this question](https://stackoverflow.com/questions/24746397/how-can-i-convert-an-array-to-a-tuple) – Joakim Danielson Feb 27 '21 at 21:24

2 Answers2

2

It seems like they work with tuples but not arrays for some reason

The reason is that a tuple is a multi-value type, each value is evaluated separately, on the other hand an array is one value.

A valid syntax is

switch arr {
    case arr where arr[0] == 0 && arr[5] == 2 : print("Yay")
    
    default: print("Nay")
}

The tuple syntax would be something like

switch (arr[0], arr[1], arr[2], arr[3], arr[4], arr[5], arr[6], arr[7], arr[8]) {
    case (0,_,_,2,1,0,_,_,_): print("Yay")
    
    default: print("Nay")
}
vadian
  • 274,689
  • 30
  • 353
  • 361
0

This is heavily implied by Joakim's and vadian's responses, but for the benefit of other beginners that might come across this- a very simple conversion of the array to a tuple (as below) seems to work perfectly for what I was trying to accomplish in the first place, and only really requires addition of one intermediary variable and replacing some brackets with parentheses:

var arr2 = [0,1,0,1,0,2,1,0,0]
let arr2AsTuple = (arr2[0],arr2[1],arr2[2],arr2[3],arr2[4],arr2[5],arr2[6],arr2[7],arr2[8])

switch arr2AsTuple {
case (1,_,_,_,_,_,_,_,_): print("Yay")

default: print("Nay")
}