4

I'm using Mathematica and have a set of variables (A,B,C,D,...) with properties A=(blue, big, rounded), B=(red, small, spiky), and so forth. Those properties can be common between variables. What would be the best, general way to find all variables that share a common property (of being, for instance, small)? Thanks.

Sjoerd C. de Vries
  • 16,122
  • 3
  • 42
  • 94
PFD
  • 223
  • 1
  • 6

1 Answers1

7

Here's a list of possible properties:

In[1]:= properties={"red","green","blue","big","small","rounded","spiky"};

And here's a list of objects with some of those properties

In[2]:= list={{"blue","big","rounded"},{"red","small","spiky"},
              {"red","big","rounded"},{"blue","small","spiky"}};

You can find all objects that have the property of, e.g., being "blue" using Select

In[3]:= Select[list, MemberQ[#,"blue"]&]
Out[3]= {{blue,big,rounded},{blue,small,spiky}}

This could be wrapped up into a function. Although how I would write that function would depend on the data structures and usage that you're planning.


Actually, I just reread you question you have a list of objects with some properties and you want to refer to those objects by name. So you probably want something more like

In[1]:= listProperties["A"]:={"blue","big","rounded"}
        listProperties["B"]:={"red","small","spiky"}
        listProperties["C"]:={"red","big","rounded"}
        listProperties["D"]:={"blue","small","spiky"}

Above I defined some properties that are associated with certain strings. You don't have to use strings in the above or below, and you can create a better structure than that if you want. You could also make a constructor to create the above, such a constructor could also check if the list of properties supplied is of the right form - i.e. does not have contradictory properties, are all in a list of known properties etc...

We then define a function to test if an object/string has a certain property associated with it

In[2]:= hasProperty[obj_, property_]:=MemberQ[listProperties[obj],property]

You might want to return an error or warning message if listProperties[obj] does not have a definition/rule associated with it.

Use Select to find all "objects" in a list that have the associated property "blue":

In[3]:= Select[{"A","B","C","D"}, hasProperty[#,"blue"]&]
Out[3]= {A,D}

There are other ways (probably better ways) to set up such a data structure. But this is one of the simplest ways in Mathematica.

Simon
  • 14,631
  • 4
  • 41
  • 101
  • Thanks a lot Simon, that's exactly what I needed. Sorry for not being able to thumbs up. – PFD Jul 20 '11 at 06:18
  • @Simon I was thinking of using `Options` to set the attributes independently of the vars values. Not sure if that is what the OP wants. – Dr. belisarius Jul 20 '11 at 06:20
  • It's all there, @belisarius. Just wanted to be add some properties to built-in mathematica data and include the new data to classify it. Tx. – PFD Jul 20 '11 at 06:31
  • 1
    @belisarius: Using `Options` gets messy really quickly. Last time I tried to do something other than simple options with them ([here](http://stackoverflow.com/q/5708208/421225)) I got very quickly disillusioned. When/If I rewrite and extend that matrix code, I'm going to use just optional arguments. Not `Options`. – Simon Jul 20 '11 at 06:32
  • @Simon After looking at your code I think I'll not try that way ... :) – Dr. belisarius Jul 20 '11 at 06:40