On Tue, 23 Feb 2010 16:09:29 -0800 (PST)
Base <[email protected]> wrote:
> Hi All -
>
> So this may be an extraordinary dumb question (even for me...) but is
> there such a thing as a map with compound keys?
>
> For example lets say that I have a data set that looks like....
>
> Cat Gender item-Id's
> 1 M 1 2 3 4 5 6 7 8 9
> 1 F 2 4 5 6607 43 54 234
> 2 M 1 2 3 4 5 6 7 8 44 6 23 44
> 2 F 2 4 6 8 10 12 17 38 55
> 3 M 1 2 3 4
> 3 F 2 4 6 8 33 45 10 12
> ...
>
> where I would want to do a look up on both the category and the
> gender.
>
> I could do map - in - map, or do something like a (str cat gender) to
> amalgamate 2 fields to set the key but I was just wondering if this
> even existed.
>
> How do you all model this data?
You can use a map-in-map structure, though given that your maps always
have the same two keys, a struct might be a better option:
(defstruct cat-entry :male :female)
{1 (struct cat-entry [1 2 3 4 5 6 7 8 9] [ 2 4 5 6607 43 54 234]),
2 (struct cat-entry [1 2 3 4 5 6 7 8 44 6 23 44] [ 2 4 6 8 10 12 17 38 55]),
3 (struct cat-entry [1 2 3 4] [2 4 6 8 33 45 10 12])}
and access the fourth mail like so ((data 4) :male). Or even, with
(def M :male) ((data 4) m).
Or even store vectors in the map:
{1 [[1 2 3 4 5 6 7 8 9] [ 2 4 5 6607 43 54 234]]),
2 [[1 2 3 4 5 6 7 8 44 6 23 44] [ 2 4 6 8 10 12 17 38 55]]),
3 [[1 2 3 4] [2 4 6 8 33 45 10 12]])}
which makes the access look like (assuming appropriate definitions for
M and F): ((data 4) M)
Alternatively, amalgamation works fine, though you probably want to
amalgamate with vector instead of str. That prevents inadvertent
collisions in cases where the elements in are similar (not a problem
for you). Again, assuming appropriate definitions for M and F:
{[1 M] [ 1 2 3 4 5 6 7 8 9],
[1 F] [ 2 4 5 6607 43 54 234],
[2 M] [ 1 2 3 4 5 6 7 8 44 6 23 44],
[2 F] [ 2 4 6 8 10 12 17 38 55],
[3 M] [ 1 2 3 4],
[3 F] [ 2 4 6 8 33 45 10 12]})
And access looks like (data [4 M]).
Just choose whichever representation is easiest to manipulate.
I just posted a blog entry that uses both techniques - maps in a map
indexed by a vector of words - in solving an interview problem at
http://mired.wordpress.com/2010/02/23/phrase-groups-in-clojure/.
> I was using Incanter's data set $where statements for this but have
> been having performance issues with it and am trying to speed up this
> operation. I have a data set with around 130,000 rows so a map would
> really help pare things down in a hurry...
In that case, you may want to call hash-map on a lazy sequence
extracting the rows from a data set.
> Sorry for the *really bad* question!
It's not really bad. Being able to use arbitrary things for map
indexes is surprising the first time you encounter it.
<mike
--
Mike Meyer <[email protected]> http://www.mired.org/consulting.html
Independent Network/Unix/Perforce consultant, email for more information.
O< ascii ribbon campaign - stop html mail - www.asciiribbon.org
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en