4
$\begingroup$

Consider the following rule:

$rule={"Period ID"|p:"Period":>p};

This rule will match "Period ID" and "Period". When it matches "Period" it returns "Period" but when it matches "Period ID" it returns Sequence[]. I want it to return "Period" in both cases.

{"Period ID","ID","Period"}/.$rule

{"ID", "Period"}

Within the $rule I don't want to duplicate the string. For example, the following $rule would work:

$rule={"Period ID"|"Period"->"Period"};

and returns the desired:

{"Period", "ID", "Period"}

But the $rule has "Period" appearing twice. How can I do this using RuleDelayed?

$\endgroup$
1
  • 1
    $\begingroup$ How about With[{str = "Period"}, $rule = {"Period ID" | str -> str}]? $\endgroup$
    – xzczd
    Commented Jun 16 at 7:22

1 Answer 1

2
$\begingroup$

I really don't think that the duplication is egregious in this case, but you could avoid it with something like this:

rule = {str_String?(StringStartsQ["Period"]) :> StringTake[str, 6]}

Response to comment

If there is generally no relationship between the strings you want to transform (I previously assumed that the "targets" each start with "Period"), but you always have one string that you need to transform by identity, then why include that identity transform in your rule at all? You can just assume the identity transform implicitly (as you did for "ID").

$rule = {"Period ID" -> "Period"};
{"Period ID", "ID", "Period"} /. $rule
(* {"Period", "ID", "Period"} *)
$\endgroup$
2
  • $\begingroup$ "Period" and "Period ID" are just examples. In the general case, the strings may have nothing in common. $\endgroup$
    – user13892
    Commented Jun 16 at 5:37
  • $\begingroup$ @user13892 I guess I was confused. See update. $\endgroup$
    – lericr
    Commented Jun 16 at 15:49

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