3
$\begingroup$

This is a new twist of an earlier question about how to get variable names as strings from a function.

I would like to have a function that returns a list of variable names, each being a string, from a list of variables. The goal is to be able to generate a grid that lists the variable name in one column, and the variable values in another, and to iterate this over a list of variables. I have tried:

a = {1, 2, 3, 4, 5};
b = {2, 4, 6, 8};
c = {1, 3, 5, 7};

Clear[varName]
SetAttributes[varName, HoldFirst]
varName[var_] := SymbolName[Unevaluated@var];

{varName[#], Length[#]} & /@ {a, b, c}

which does not yield symbol name. The closest I have come is this (using Length as an example function)

{ToString@#, Length @@ #} & /@ HoldForm /@ Unevaluated@{a, b, c}

{{"a", 5}, {"b", 4}, {"c", 4}}

What I can't figure out is how to define this as a function

func[varlist_]:={ToString@#, Length @@ #} & /@ HoldForm /@ Unevaluated@varlist

func[{a,b,c}]

Desired result: {{"a", 5}, {"b", 4}, {"c", 4}}

Thanks!

$\endgroup$
3
$\begingroup$
SetAttributes[fun, {HoldFirst, Listable}]
fun[var_] := {SymbolName[Unevaluated[var]], Length[var]}
fun[{a, b, c}]

{{"a",5},{"b",4},{"c",4}}

$\endgroup$
  • $\begingroup$ Now why didn't I think of that? +1 :^) $\endgroup$ – Mr.Wizard Feb 17 '17 at 2:45
  • $\begingroup$ @Mr.Wizard Well,glad to know I am better a little. :) $\endgroup$ – yode Feb 17 '17 at 3:32
3
$\begingroup$

I would first define a function that can get just the variable names:

SetAttributes[varNames, HoldAll]
varNames[{varList__}]:=List @@ ToString /@ Unevaluated /@ Hold[varList]

Then, you can use the function:

SetAttributes[func, HoldAll]
func[v_List] := Thread[{varNames[v], Length/@v}]

Example:

a = {1, 2, 3, 4, 5};
b = {2, 4, 6, 8};
c = {1, 3, 5, 7};

func[{a,b,c}]

{{a,5},{b,4},{c,4}}

$\endgroup$
3
$\begingroup$

First of all this might be a simpler approach:

Cases[
  Unevaluated[{a, b, c}],
  var_ :> {ToString @ Unevaluated @ var, Length @ var}
]
{{"a", 5}, {"b", 4}, {"c", 4}}

To make this a function:

Attributes[func] = HoldFirst;

func[x_List] := 
    Cases[
      Unevaluated[x],
      var_ :> {ToString @ Unevaluated @ var, Length @ var}
    ]
$\endgroup$
  • $\begingroup$ Elegant and functional, as always!! Thank you. $\endgroup$ – GraphMan Mar 2 '17 at 15:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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