Switch case in closure form not matching properly - regex

I'm trying to make a switch case based on partial strings using Groovy's pattern matching. I've already got this working -
String s = "abc";
switch(s){
case { it =~ /b/ } :
//this works
break;
.....
}
But when I try to abstract out the closure I run into issues -
String s = "abc";
def partialMatch = {string, pattern -> string =~ /$pattern/}
switch(s){
case partialMatch(s, "b"):
//this doesn't work
break;
.....
}
It seems like the match is working, but the case still doesn't trigger for some reason. Why is that?

You'd need to put partialMatch in a Closure for it to be executed by the switch:
case {partialMatch(s, "b")}:

Related

Convert a boring list of switch statements to something shorter and pleasing to look at?

I have a switch statement that runs like this
switch (abc) {
case FILE_0:
lf = m_a->olf[0];
kf = m_a->pkf[0];
break;
case FILE_1:
lf = m_a->olf[1];
kf = m_a->pkf[1];
break;
.
.
default:
LOG_ERR << "Wrong type to check";
return 0;
}
This happens about 30 times and i end up with 30 cases in this single switch.
Any way to shorten it in C++ 11 ? E.g. using templates.
Your code ain't that big to be sure about the intent, though, from what I can see in the snippet, you actually want to convert the symbolic value into an index. (Can I assume this is an enum?)
What I would do is to move that code into a separate function:
auto fileEnumToIndex(FileEnum file) {
switch (file) {
case FILE_0: return 0;
case FILE_1: return 1;
default: __builtin_unreachable();
}
}
Your code than changes to:
auto index = fileEnumToIndex(abc);
lf = m_a->olf[index];
kf = m_a->pkf[index];
If the FileEnum is a real enum, you can change the code in the function fileEnumToIndex to a simple static_cast
To cover the default case, you could return a std::optional and use the std::nullopt case to do some error handling. However, when FileEnum is an actual enum, I would assume error handling when you determine that value.
You can create a map of abc and the indice and use that for determining the indice.
// somewhere, maybe outside functions
static const std::unordered_map<abc_type, int> table = {
{FILE_0, 0},
{FILE_1, 1},
...
};
// inside function
auto idx_itr = table.find(abc);
if (idx_itr != table.end()) {
lf = m_a->olf[*idx_itr];
kf = m_a->pkf[*idx_itr];
} else {
// default case
}

Using a switch in a do..while loop, in C++

A simple programm that reads strings, and responds using a switch;
in this do-while loop containing a switch, I am able to run case 1-4 with no issues, but once i hit the default case, the programme simply loops the default case over and over again the code is as follows;
do { switch ( switchstring (entry, input) )
/*the switchstring function is one 1 wrote to convert a given entry(string),
into an input(integer)*/
{
case 1:
//code
repeat = 2;
break;
case 2:
//code
repeat = 2;
break;
case 3:
//code
repeat = 2;
break;
case 4:
//code
repeat = 2;
break;
default:
//code
repeat = 1;
break;}} while(repeat == 1);
the 2nd question is regarding my switchstring() function; is there a way to change the switch function such that it reads;
case (insert string):
i.e. so that I can remove the entire switchstring() function
thanks in advance!
Show us how switchstring (entry, input) works.
The problem you are facing is because, in default you do the following:
repeat = 1;
Which makes while(repeat == 1) always true. And then switchstring (entry, input) always return something that makes your switch block always go the the default case again.
When no case will be true in switch, then it will go in default case of switch and you are specifying repeat=1; in default. After that while condition will be checked and it will be true because repeat is 1, again it will go to do and check condition, your switch function will return something and it will go to default.
To solve 2nd question regarding your switchstring() function, you have to show your code what you are doing in that function, So that i can give you best suggestion.

PCRE PartialMatch dynamic number of groups

My app has user defined regular expression patterns which may contain up to 3 capturing groups. Is there a better way to implement the following code?
std::string glyph1, glyph2, glyph3;
switch (regex.NumberOfCapturingGroups())
{
case 0:
default:
found = regex.PartialMatch(word);
break;
case 1:
found = regex.PartialMatch(word, &glyph1);
break;
case 2:
found = regex.PartialMatch(word, &glyph1, &glyph2);
break;
case 3:
found = regex.PartialMatch(word, &glyph1, &glyph2, &glyph3);
break;
}
if (found) {
// ...
}
Unfortunately, the returned value is false if the regex would match but there were less capturing groups then requested.
You could use a list or a vector for this problem. Instead of overloading the function make one with a parameter vector<std::string> glyph and a int n for the regex.NumberOfCapturingGroups().
vector<std::string> glyph;
regex.PartialMatch(word, glyph, regex.NumberOfCapturingGroups());
if (found) {
// ...
}
Then just use glyph[i] to access elements.

how to use regex in switch case in expect script?

Normally, switch case in expect looks like this:
switch -- $count \
1 {
set type byte
} 2 {
set type word
} big {
set type array
} default {
puts "$count is not a valid type"
}
I need to use regex operators such as | or & - how can I do that?
The below example does not work with expect code :
switch -- $variable \
("a"|"b"|"c") {
do something
}
("a"|"b"|"c") represents a or b or c, but it does not seem to work.
How do I use such statements in switch or may be an and statement?
Use the -regexp option for the command, and brace the expression the Tcl way. Also, you can use braces around all the switches so you don't have to use line continuations.
switch -regexp -- $variable {
{a|b|c} {
do something
}
{^[def].*(?:g|h|i)} {
do a different thing
}
default {
do something else
}
}
http://tcl.tk/man/tcl8.5/TclCmd/switch.htm
http://tcl.tk/man/tcl8.5/TclCmd/re_syntax.htm

c++ cannot appear in a constant-expression| [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How do I select a range of values in a switch statement?
I've been getting some errors, and I've been searching for some time now, but I have no idea what is the cause of the errors. (I'm quite new to programming.)
Here are the errors I'm getting:
error: 'Essais' cannot appear in a constant-expression| (line 200)
warning: overflow in implicit constant conversion| (line 202)
I have case and cote:
char AfficherCote (int Essais)
{
char Cote;
switch (Essais)
{
(line200) case Essais<=20:
{
(line 202) Cote='Excellent';
return (Cote);
break;
}
case Essais<=40:
{
Cote='Très bon';
return (Cote);
break;
}
case Essais<=60:
{
Cote='Bon';
return (Cote);
break;
}
case Essais<=80:
{
Cote='Moyen';
return (Cote);
break;
}
case Essais<=100:
{
Cote='Muvais';
return (Cote);
break;
}
case Essais>=100:
{
Cote='Très mauvais';
return (Cote);
}
}
}
switch-case only works with constant values(*) (such as 3 or 'a'), not with ranges (such as <=100). You also must not include the variable name in the case statement. Correct syntax would be as follows:
switch (Essais)
{
case 1:
/* ... */
break;
case 2:
/* ... */
break;
default:
/* ... */
}
If you need range tests, use if instead of switch-case:
if (Essais <= 80)
return "Cote";
else if (Essais <= 100)
return "Muvais";
Also note that you can't use single quotation marks ' for strings. Use double quotation marks " instead, and use variables of type std::string (not char) to store strings.
(*) To be precise, the condition given in the case statements must be a constant expression of integral type, enumeration type, or class type convertible to integer or enumeration type (see §6.4.2/2 of the C++ Standard for details).
That's not how switch blocks work. You would need to do something like this instead:
switch (Essais) {
case 20:
...
case 40:
...
case 60:
...
/* etc, etc */
}
Each case compares the value in the switch statement against a specific constant value. If they are equal, that block is executed. In your code, the compiler is complaining because an expression like Essais<=20 is not a constant that it can evaluate at compile time.
Given what you are trying to do, an if ... else if ... else chain would be more appropriate. switch blocks can only test against specific values and can't handle testing ranges, which is what it appears you are trying to do.