As most regular users, I have developed utility functions complementing the Wolfram language for frequent tasks.
In particular, I have variations on Cases (see example definitions below). But I have trouble to add to them the pattern transformation capabilities of Case, such as Cases[ {1,3,5,6}, a:_Integer?EvenQ :> a/2 /; (a>0)] because my current versions rely on Position, not on Cases. I usually can do what I want with my CaseMap function or other classical means at the expense of legibility and maintainability but I am also curious of the right way to construct such a pattern handling syntax.
CaseSort sorts specific elements disseminated in a structure
CaseSort[k_List, p_] := CaseSort[k, p, 1] CaseSort[k_List, p_, z__] := Module[{kb = k, csz}, MapThread[ (Part[kb, Sequence @@ #2] = #1 ) &, {Sort[ Extract[k, csz = Position[k, p, z]]], csz}]; kb] CaseSortBy is a straightforward variation on it
CaseSortBy[k_List, f_, p_] := CaseSortBy[k, f, p, 1] CaseSortBy[k_List, f_, p_, z__] := Module[{kb = k, csz}, MapThread[ (Part[kb, Sequence @@ #2] = #1 ) &, {SortBy[ Extract[k, csz = Position[k, p, z]], f], csz}]; kb] CaseMap is a cousin of MapAt and Replace
CaseMap[f_, k_List, p_] := CaseMap[k, p, 1] CaseMap[f_, k_List, p_, z__] := Module[{kb = k, csz}, MapThread[ (Part[kb, Sequence @@ #2] = f[#1] ) &, {Extract[k, csz = Position[k, p, z]], csz}]; kb] CaseMapIndexed allows to have the positional context of the element when modifying it.
CaseMapIndexed[f_, k_List, p_] := CaseMapIndexed[k, p, 1] CaseMapIndexed[f_, k_List, p_, z__] := Module[{kb = k, csz}, MapThread[ (Part[kb, Sequence @@ #2] = f[#1, #2] ) &, {Extract[k, csz = Position[k, p, z]], csz}]; kb]
CaseSort[list_List, r:(_Rule | _RuleDelayed)] := (* stuff *)? $\endgroup$