0

I am reading a file with Get[] that contains a semi-colon separated sequence of sub-scripted definitions like this:

data[1] = {stuff};
data[5] = {otherStuff};
data[99] = {yetMoreStuff};

What is the cleanest way to programatically decide for what values of i is data[i] defined? A list of the indices would be nice, e.g. {1, 5, 99}.

A hacky way would be to loop through the range of possible values to see which ones don't have head "data" (e.g. Select[data/@Range[1,1000],(Not[MatchQ[#,_data]])?]), but this is unattractive since it isn't general (e.g. it won't find data[dog] = "Max"; if we remove the integer subscript requirement) and assumes that one can choose an upper bound. It would also be slow and waste memory.

Codie CodeMonkey
  • 7,669
  • 2
  • 29
  • 45
  • Related: http://stackoverflow.com/q/5086749/618728 http://stackoverflow.com/q/7165169/618728 and http://mathematica.stackexchange.com/q/7972/121 – Mr.Wizard Sep 15 '12 at 12:56

2 Answers2

4

I'm still not at my Mathematica machine but it occurs to me that DownValues[data] will probably return a list of rules that you might be happy to manipulate to get out the is. Perhaps something like this;

Cases[DownValues[data],RuleDelayed[HoldPattern[data[i_Integer]],rhs_]:>i]
High Performance Mark
  • 77,191
  • 7
  • 105
  • 161
0
data[1] = {stuff};
data[5] = {otherStuff};
data[99] = {yetMoreStuff};

Cases[
 DownValues @ data,
 _[_@_@x_Integer, _] :> x
]
{1, 5, 99}
Mr.Wizard
  • 24,179
  • 5
  • 44
  • 125