Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

Tables often come with column headers. Indexing the columns with the header is a natural thing to do. Although a proper dictionary is the usual solution in such a case, I find it often practical and elegant to index these through the symbol corresponding to the column header string. So say: I have an array:

mtvguests = {{Last Name, First Name},{Kolmogorov, Andrei},{Milankovic, Milutin}}

mtvguests[[All, lastName]] is a fairly natural and readable syntax.

The following two functions help towards this end:

SetAttributes[SymbolValidWMMA, Listable];
Options[SymbolValidWMMA] := {camelCase -> False, RulesStringPatterns->{"/"->"or"}}
    SymbolValidWMMA[s_String, OptionsPattern[]] := 
     Fold[StringReplace[#1, #2] &, s, 
      Join[ OptionValue[RulesStringPatterns], If[OptionValue[camelCase], {Except[WordCharacter] ~~ x_ :> ToUpperCase[x], 
         StartOfString ~~ Whitespace ... ~~ x_ :> 
          ToLowerCase[x]}, {}], {Whitespace -> "", 
        StartOfString ~~ x:DigitCharacter :> "d"<>x, 
        Except[WordCharacter] -> "" }]];

(I am not a big fan of camel case but in this case it comes as handy).

Options[IndicesFromStrings] := 
Join[Options[SymbolValidWMMA], {Prfx -> "", Sfx -> "", 
                Ctxt -> ""}];
            IndicesFromStrings[ls_List, opts : OptionsPattern[]] := 
              (ToExpression[#1 <> "=" <> ToString[First@#2]]) & 
               ~MapIndexed~ (If[OptionValue[Ctxt] != "", OptionValue[Ctxt] <> "`", 
                    ""] <> OptionValue[Prfx] <> 
                   SymbolValidWMMA[#, 
                    Sequence @@ FilterRules[{opts}, Options[SymbolValidWMMA]]] <> 
                   OptionValue[Sfx] & /@ ls);

An example.

mtvguests = {{"Kolmogorov", "Andrei"}, {"Milankovic", "Milutin"}}; 
Prepend[mtvguests, {"Last Name", "First Name"} ] // TableForm

Then

IndicesFromStrings[{"Last Name", "First Name", "Cycles/Operators", 
  "2_2_Tu"}, camelCase -> True]

yields:

{"lastName", "firstName", "cyclesorOperators", "d22Tu"}

And

mtvguests[[All, lastName]]

would return:

{"Kolmogorov", "Milankovic"}

The symbol mangling can be tweaked:

IndicesFromStrings[{"Last Name", "First Name", "Cycles/Operators", 
  "_2_Tu"}, Ctxt -> "mtv", camelCase -> False, 
 RulesStringPatterns -> {DigitCharacter -> "nb", "/" -> "", 
   "_" -> "U"}]

would now return:

{"mtv`LastName", "mtv`FirstName", "mtv`CyclesOperators", "mtv`UnbUTu"}

The previous works. Now for the question: I am not sure how to make the following work:

IndicesFromStrings[ls_List, opts : OptionsPattern[]] := 
  (Set[ReleaseHold[ToExpression[#1]], ToString[First@#2]]) &
    ~MapIndexed~(If[OptionValue[Ctxt] != "", OptionValue[Ctxt] <> "`", 
        ""] <> OptionValue[Prfx] <> 
       SymbolValidWMMA[#, 
        Sequence @@ FilterRules[{opts}, Options[SymbolValidWMMA]]] <> 
       OptionValue[Sfx] & /@ ls);
share|improve this question
5  
If you've a problem with Set[], then post a minimal example. The rest of the code (notwithstanding how clever it could be) is just impedance to understand the question. –  belisarius Apr 20 at 17:49
3  
I do not agree with the down-votes on this question. While a more clear and concise summary would indeed be helpful, it is also often helpful to include the context of the issue to illustrate the actual problem that needs to be solved, thereby facilitating answers of broader scope instead of mere bug-fixes for something that may be a poorly conceived approach to begin with. While in time a standard of more tightly written questions is good, this is ostensibly Trad Dog's first question here; please let us be more friendly. –  Mr.Wizard Apr 20 at 19:49
1  
I can't follow your code, too advanced for me. But when I wanted once to index by column and give it a tag/name, I simply made few costants, like this: NAME=1;DATE=2;. then for matrix say m={{"joe doe","1/1/2001"},{"joe doe 2","1/1/2002"}}, I would write m[[All,NAME]] and m[[2,DATE]] and so on. it works and was easy to handle. Not as nice as dictionary ofcourse. Just had to remember to make sure the names of columns and the index matched what I wanted. –  Nasser Apr 20 at 22:42
    
@Mr.Wizard Appreciate the accolade. There are essentially two issues with the first implementation of IndicesFromStrings. First, it could be more elegant and straight-forward (this is just setting several generated symbols to some numerical values). And, in the current form, because the operation perform is akin to a "set" it is rather unexpected that it does return some expression. –  Trad Dog Apr 21 at 20:31
    
@Nasser. I appreciate your approach and that's what I would do for a long time. However, when importing tables repetitively, the boiler-plate code involved becomes tedious on the long run. Handling the process in an automatised way comes then naturally. –  Trad Dog Apr 21 at 20:35
show 1 more comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.