2
$\begingroup$
  Is there a solution?

  (* after the suggestions of nice people comes here   
   the whole story: *)

mengeA = {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "A", "Q", "P", "B", "E", "F", "G", "H", "L", "M", "N", "O", "P", "A", "F", "M", "S", "E", "Q", "R", "S", "T", "U", "V", "W", "X", "Y",  "Z"};



spMengeA = {"A", "C", "E", "K", "M", "N", "O", "Q", "S","U", "W", "Y"};


   ClearAll[takeFollowingMembersFrom];
   takeFollowingMembersFrom[menge_List, firstElem_String, 
   numberOfElemTotal_Integer] := 
   Module[{a0, a1, a2, a3, allPos, myFun, pos},
   ClearAll[myFun];
   SetAttributes[myFun, HoldFirst];
   myFun[li_, item_String] := 
   MemberQ[Symbol["sp" ~~ Capitalize@SymbolName[Unevaluated@li]], 
   item];

  pos = DeleteDuplicates[
  Flatten[Position[menge, #] & /@ 
   Select[menge, 
    StringMatchQ[#, firstElem] && myFun[menge, #] &]]]; 
  allPos = {{#}} & /@ pos; 
  a1 = Extract[menge, 
   Flatten[FoldList[Plus, #, Table[1, numberOfElemTotal - 1]], 
    1]] & /@ allPos];

   takeFollowingMembersFrom[mengeA, "A", 3]

  (*and I want to get:  {{"A","B","C"},{"A","Q","P"},{"A","F","M"}} *)
$\endgroup$
1
  • 1
    $\begingroup$ You’d need to set a Hold attribute (perhaps HoldFirst) for your function myFun. You can use SetAttributes. $\endgroup$
    – MarcoB
    May 18, 2020 at 14:29

2 Answers 2

1
$\begingroup$
ClearAll[myFun]
SetAttributes[myFun, HoldFirst]
myFun[li_, item_String] :=
 MemberQ[
   Symbol["sp" ~~ Capitalize@SymbolName[Unevaluated@li]],
   item
 ]   

myFun[mengeA, "K"]           (* Out: True  *)
myFun[mengeA, "B"]           (* Out: False *)
$\endgroup$
2
  • $\begingroup$ Unfortunately the suggestion won't work, because the element "K" has to be able to change to for example "T" oder "W" as part of an other function. $\endgroup$
    – Andreas
    May 18, 2020 at 18:10
  • $\begingroup$ @Andreas See the edit. $\endgroup$
    – MarcoB
    May 18, 2020 at 18:39
0
$\begingroup$

With the pattern li_List, evaluation happens and that should be avoided to achieve what you are doing.

Next, to prevent mengeA getting evaluated before myFun1 sees it we need to either:

A) wrap it in Unevaluated as below or

B) myFun1 needs to have the HoldAll or HoldFirst attribute as suggested by MarcoB.

ClearAll[myFun1]
myFun1 := ToExpression@StringJoin["sp", Capitalize@ToString@Unevaluated@#]&

MemberQ[myFun1[Unevaluated@mengeA], "K"]

(* True *)
$\endgroup$
3
  • 1
    $\begingroup$ 1) Your approach requires the user to add Unevaluated each time the function is called, which is time-consuming and error-prone; also, since you would never call this function without the Unevaluated, it should really be included inside its definition. 2) Since you defined myFun as a pure function, you do not need to use SetDelayed to force the re-evaluation of the definition at each call; Set would do. $\endgroup$
    – MarcoB
    May 18, 2020 at 15:28
  • $\begingroup$ @MarcoB Fair points. I am just suggesting a solution. $\endgroup$ May 18, 2020 at 15:31
  • $\begingroup$ Unfortunately the suggestion won't work, because the element "K" has to be able to change to for example "T" oder "W" as part of an other function. $\endgroup$
    – Andreas
    May 18, 2020 at 18:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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