Suppose I have myStrList
, a list of one-character strings:
myStrList = {"A", "a", "B", "b"};
I wish to create a function that will return True
if a string is either "A"
or "a"
, and False
otherwise. I wish to Map
this function across the list myStrList
.
- Method (1). One way to do this is to use
MemberQ
to test if a string is a member (element) of the list{"A", "a"}
. This method gives the expected output:
(* Method (1): using MemberQ *)
Map[MemberQ[{"A", "a"}, #] &, myStrList]
(* {True, True, False, False} *)
- Method (2). Another way is to use
MatchQ
with a pattern object involvingAlternatives
(or, equivalently,|
). This method also gives the expected output:
(* Method (2): using MatchQ and Alternatives (|) *)
Map[MatchQ[#, Alternatives["A", "a"]] &, myStrList]
Map[MatchQ[#, "A" | "a"] &, myStrList]
(* {True, True, False, False} *)
(* {True, True, False, False} *)
- Method (3). Still another way is to use
Or
(or, equivalently,||
), the logical OR. Again, this method gives the expected output:
(* Method (3): using Or (||) *)
Map[Or[# == "A", # == "a"] &, myStrList]
Map[# == "A" || # == "a" &, myStrList]
(* {True, True, False, False} *)
(* {True, True, False, False} *)
Is there a way to condense method (3), so that it is less verbose? Instead of asking whether # == "A"
OR # == "a"
, can I ask whether # == "A"
OR "a"
? I tried the following:
Map[# == Or["A", "a"] &, myStrList]
Map[# == ("A" || "a") &, myStrList]
(* {"A" == ("A" || "a"), "a" == ("A" || "a"),
"B" == ("A" || "a"), "b" == ("A" || "a")} *)
(* {"A" == ("A" || "a"), "a" == ("A" || "a"),
"B" == ("A" || "a"), "b" == ("A" || "a")} *)
Neither of the above gives the expected output. It looks as though the equality test is being held. I notice that Or
(or, equivalently, ||
) has attribute HoldAll
:
Attributes[Or]
(* {Flat, HoldAll, OneIdentity, Protected} *)
Could it be that I need to use Evaluate
to force the evaluation of # == ("A" || "a")
? It doesn't seem that Evaluate
helps in this regard:
Map[Evaluate[# == Or["A", "a"]] &, myStrList]
Map[Evaluate[# == ("A" || "a")] &, myStrList]
Map[# == Evaluate[Or["A", "a"]] &, myStrList]
Map[# == Evaluate[("A" || "a")] &, myStrList]
(* {"A" == ("A" || "a"), "a" == ("A" || "a"),
"B" == ("A" || "a"), "b" == ("A" || "a")} *)
(* {"A" == ("A" || "a"), "a" == ("A" || "a"),
"B" == ("A" || "a"), "b" == ("A" || "a")} *)
(* {"A" == ("A" || "a"), "a" == ("A" || "a"),
"B" == ("A" || "a"), "b" == ("A" || "a")} *)
(* {"A" == ("A" || "a"), "a" == ("A" || "a"),
"B" == ("A" || "a"), "b" == ("A" || "a")} *)
Nor does it seem that using Simplify
or FullSimplify
will evaluate the expressions:
Simplify /@ {"A" == ("A" || "a"), "a" == ("A" || "a"),
"B" == ("A" || "a"), "b" == ("A" || "a")}
FullSimplify /@ {"A" == ("A" || "a"), "a" == ("A" || "a"),
"B" == ("A" || "a"), "b" == ("A" || "a")}
(* {"A" == ("A" || "a"), "a" == ("A" || "a"),
"B" == ("A" || "a"), "b" == ("A" || "a")} *)
(* {"A" == ("A" || "a"), "a" == ("A" || "a"),
"B" == ("A" || "a"), "b" == ("A" || "a")} *)
The solution to this may be obvious, but it's not obvious to me. How can I force testing expressions like "A" == ("A" || "a")
to evaluate? Or where am I going wrong conceptually?
# == Or["A", "a"] &
does not look right to me. The syntax ofOr
is not like this. But why not just use something likeAnyTrue[myStrList,Or[#=="A",#=="a"]&]
. I know you said you wanted to useMap
. In Mathematica there are many ways to do the same thing. I see nothing wrong with your earlier tries also. But the last one, yourOr
usage is not correct. You can fix it by doingOr[# == "A", # == "a"]
i.e. move the#
inside. $\endgroup$StringMatchQ["A" | "a"]@myStrList
? $\endgroup$ToUpperCase[#] == "A" & /@ myStrList
$\endgroup$AnyTrue[]
will "create a function that will returnTrue
..." as you say you want. Further, it will returnTrue
as soon as it runs into an"a"
or an"A"
, whereasMap[]
will pointlessly continue to check all remaining strings. $\endgroup$Or[]
is not way represent alternative values. It's a logical connective to connect boolean expressions (whose value is presumed to be from the set{True, False}
). Since a string does not represent a boolean expression, Mathematica does not know what to do with it and leaves it alone. About the only evaluation one can get is("a" || "A") == ("A" || "a")
since each side is identical. NowOr
could connect to equalities, as inThread[# == ("A" || "a"), Or] & /@ myStrList
. $\endgroup$