0
$\begingroup$

I am trying to learn "core" patterns so I can start using them more often. Consider I am trying to solve the following problem.

data = {2,{4,2,3},5,{7,3},{},4,1} (assume List will not appear beyond level 1)

To get only non-list elements I can use the following pattern.

data //. {x:___,{___},y:___}:>{x,y}

Is there a way to do the same using a sub-pattern replacement (regular expressions allow that)

data//.{___,t:{___},___}:>Nothing (I want to only replace t with Nothing)

Next how do I get only list elements.

data //. (...)

Allowed functionality:

• Basic Pattern Objects

• Composite Patterns

• Restrictions on Patterns

• Pattern Defaults

<< Pattern Matching Functions are NOT allowed except for the following >>

Replace (third argument levelspec NOT allowed)

ReplaceAll

ReplaceRepeated

$\endgroup$

closed as off-topic by MarcoB, b3m2a1, Pinti, Henrik Schumacher, Carl Lange Feb 23 at 21:18

  • The question does not concern the technical computing software Mathematica by Wolfram Research. Please see the help center to find out about the topics that can be asked here.
If this question can be reworded to fit the rules in the help center, please edit the question.

  • 3
    $\begingroup$ It is of course a valid exercise but if you want to "start using them more often" then not using "Pattern Matching Functions" makes no sense. $\endgroup$ – Kuba Feb 20 at 12:26
  • $\begingroup$ These high level "Pattern Matching Functions" bypass the need to design composite patterns thus one never gets the chance to learn about core pattern constructs like Shortest, Longest, PatternSequence, Except etc. $\endgroup$ – user13892 Feb 20 at 12:32
  • $\begingroup$ Comments are not for extended discussion; this conversation has been moved to chat. $\endgroup$ – Kuba Feb 20 at 13:23
  • 5
    $\begingroup$ I'm voting to close this question because the artificial restrictions posed by the OP are unusual, and any effort will likely only benefit this particular case. $\endgroup$ – MarcoB Feb 20 at 18:16
5
$\begingroup$

I'm posting this only because I can't resist pattern matching puzzles. I really don't think it's good question.

data = {2, {4, 2, 3}, 5, {7, 3}, {}, 4, 1};

Question 1

data //. m : {___, t : {___}, ___} :> (m /. t -> Nothing)

{2, 5, 4, 1}

Question 2

List @@ ((tag @@ data) //. tag[x___, _Integer, y___] :> tag[x, y])

{{4, 2, 3}, {7, 3}, {}}

I would never use such code. The sane way to make these list manipulations is

Cases[data, _Integer]

{2, 5, 4, 1}

DeleteCases[data, _Integer]

{{4, 2, 3}, {7, 3}, {}}

These are just a much pattern matching solutions as the silly answers I gave above. I don't buy into the concept that only the replace group of functions are true pattern matching functions.

$\endgroup$
2
$\begingroup$

If your objective is to select conditioned on being or not being a List then Select with MatchQ and Except with pattern _List is more appropriate.

Select[MatchQ@Except[_List]]@data
{2, 5, 4, 1}

and

Select[MatchQ[_List]]@data
{{4, 2, 3}, {7, 3}, {}}

However, if you must use replacement then ReplaceRepeated (//.) is not necessary for the conditions you describe (ReplaceRepeated can lead to infinite replacement when used incorrectly). Replace at level 1 is sufficient.

Replace[data, _List -> Nothing, {1}]
{2, 5, 4, 1}

and

Replace[data, Except[_List] -> Nothing, {1}]
{{4, 2, 3}, {7, 3}, {}}

Hope this helps.

$\endgroup$
  • $\begingroup$ For reasons unknown the OP imposed a bunch of arbitrary restrictions on the problem (such as not using the third argument to Replace) $\endgroup$ – b3m2a1 Feb 20 at 23:48

Not the answer you're looking for? Browse other questions tagged or ask your own question.