1
$\begingroup$

I know the question is rather vague so, here is what I am trying to do:

Lets say we have the following function: `color[data_,variableInputs_]. Now what I want this function to do is loop over the data based on what the input variables are. Suppose, I have the following possible input variables:

"red"
"blue"
"green"
"orange"

Each input variable corresponds to a particular row in the data that I would like to loop over. Thus I want to write a function that will loop over which ever variable I pass into the function, where:

"red" -> data[[i,1]]
"blue" -> data[[i,2]]
"green" -> data[[i,3]]
"orange" -> data[[i,4]]

Without writing out a horrible nested If functions for all the various permutations of what the inputs may be. So if someone writes:

output = color[data,{"green","orange"}]

I would want the function to look like:

color[dataInput_,variableInputs_]:=(
 Table[{dataInput_[[i,3]],dataInput_[[i,4]]},{i,Length@dataInput}]
  )

Or if

output = color[data,{"blue"}]

then I would just have

color[dataInput_,variableInputs_]:=(
 Table[{dataInput_[[i,2]]},{i,Length@dataInput}]
  )

In principal I'm looking for a way to write in mathematica

color[dataInput_,variableInputs_]:=(
 Table[{"option_red","option_blue","option_green","option_orange"},{i,Length@dataInput}]
  )

where the option are whatever combination of inputs one can put in, without making use of nested If statements to account for each permutation of inputs. The order of inputs need not matter.

I hope I have explained this clearly enough.

$\endgroup$
3
$\begingroup$

I'm guessing there are easier ways to do this, but this is the best I could think of:

We'll use an association to translate colors to integers. Here, we'll assume that "red" corresponds to 1, "blue" corresponds to 2 etc just like in the example in question.

(* making switch Listable means that switch[{"red", "blue"}] evaluates to
   {switch["red"], switch["blue"]} *)
SetAttributes[switch, Listable]

With[{sw = <|"red" -> 1, "blue" -> 2, "green" -> 3, "orange" -> 4|>},
  switch[color_] := sw[color]
]

As an example of how switch works, we evaluate switch[{"red", "blue"}] to get

{1, 2}

as expected (in the question we have that "red" -> data[[i,1]] and "blue" -> data[[i,2]]).

Now, it's just a matter of defining the desired color function by making use of switch:

color[data_, variableInputs_] := Part[data, All, switch[variableInputs]]

Notice, how we've opted for Part instead of using Table. It could have been done with Table too, but it feels better having Part picking parts off of data.

Now we can test color with input a $3\times 4$ symbolic array of data. Evaluating the following

With[{data = Array[a, {3, 4}]},
  color[data, {"red", "blue"}]
]

returns

{
   {a[1, 1], a[1, 2]}, 
   {a[2, 1], a[2, 2]}, 
   {a[3, 1], a[3, 2]}
  }

as expected (hopefully).

$\endgroup$
  • $\begingroup$ Since this is a part of what i do in the function, but which is irrelevant to the question. I would need it in a Table structure. I thus modified what you did slightly to use your answer in a way that suits me. But It would be great if your answer used the Table implementation. I am happy to mark this as an answer nonetheless. $\endgroup$ – Luca Pontiggia Sep 17 '18 at 13:40
  • $\begingroup$ first off, I'm really happy you found my answer helpful! thanks for accepting it, too! As far as Table is concerned, in my experience-and as a general approach- it is not considered good practice to use iteration to get parts of expressions. This is what Part is for. You could do something like Table[dataInput[[i, switch[variableInputs]]], {i, Length@dataInput}] but that is what Part[dataInput, All, switch[variableInputs]] does better; for the toy example of the question, using them interchangeably is probably OK, but in general Part is more efficient at deconstructing expressions. $\endgroup$ – user42582 Sep 17 '18 at 14:30

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.