How to write a robust memberQ that test membership in set theory sense?

2

1

Select[{{"foo", "bar"} -> "a", {"foo", "baz"} -> 
   "a", {"foo", _} -> "a"}, MemberQ[{{"foo", "bar"}}, #[[1]]] &]

(* {{"foo", "bar"} -> "a", {"foo", _} -> "a"} *)

I'd like the answer to be {{"foo", "bar"} -> "a"}. The built-in MemberQ seems to use MatchQ for testing equality. I'd like a memberQ that uses SameQ or TrueQ[Equal[#1, #2]]&, and works for possibly funky arguments such as patterns.

qazwsx

Posted 2013-01-11T06:16:48.570

Reputation: 8 134

Answers

12

If I understand the question you are essentially displeased (for your application) that:

MemberQ[{x[1, 2], x[3, 4]}, x[1, _]]
True

What you need is Verbatim:

MemberQ[{x[1, 2], x[3, 4]}, Verbatim[ x[1, _] ]]
False
Select[
  {{"foo", "bar"} -> "a", {"foo", "baz"} -> "a", {"foo", _} -> "a"},
  MemberQ[{{"foo", "bar"}}, Verbatim @ #[[1]]] &
]
{{"foo", "bar"} -> "a"}

In case the behavior of Equal is necessary or desirable you can use that instead like this:

Select[
  {{"foo", 0.5} -> "a", {"foo", "baz"} -> "a", {"foo", _} -> "a"},
  MemberQ[{{"foo", 1/2}}, x_ /; x == #[[1]] ] &
]
{{"foo", 0.5} -> "a"}

Note 0.5 and 1/2.

Mr.Wizard

Posted 2013-01-11T06:16:48.570

Reputation: 259 163

Nice and fast +1 – Rojo – 2013-01-11T06:28:17.463

Is Verbatim the best? What about HoldPattern, Literal etc.? – qazwsx – 2013-01-11T06:46:07.920

2

@MonkeyKing HoldPattern is related but different, and "Since Version 3.0 (released in 1996), Literal has been superseded by HoldPattern."

– Mr.Wizard – 2013-01-11T06:47:43.453

I read the thread; What's the difference between (the purpose of) Cases[list, Verbatim[Rule]["foo", _]] and Cases[list, HoldPattern["foo" -> _]]? For what list the two can be different? – qazwsx – 2013-01-11T22:51:23.497

1@red3y3 as written I think those will be equivalent because nothing in "foo" -> _ can evaluate. However, consider this example: list = {"foo" -> 1, "foo" -> _, "bar" -> 2}; x = "foo"; then: Cases[list, Verbatim[Rule][x, _]] versus Cases[list, HoldPattern[x -> _]] versus Cases[list, Verbatim[x -> _]] -- observe that HoldPattern prevents x from evaluating to "foo" and therefore nothing matches. Verbatim[Rule][x, _] prevents the rule from being seen as a replacement by Cases but does not match _ literally. Verbatim[x -> _] matches "foo" -> _ literally. – Mr.Wizard – 2013-01-12T03:45:42.867