views:

52

answers:

2

Okay, I think I might be over-complicating this issue but I truly am stuck. Basically, I am trying to model a weight set, specifically an olympic weight set. So I have the bar which is 45 lbs, then I have 2 weights of 2.5 lbs, 4 of 5 lbs, and then 2 of 10, 25, 35, and 45 respectively. This makes a total of 300 lbs.

bar = 45 lbs
2 of 2.5
4 of 5
2 of 10
2 of 25
2 of 35
2 of 45

I want to model this weight set so that I have this information: the weight and the quantity of weights I have. I know I could hard-code this but I eventually want to let the user enter how many of each weight they may have.

Anyways, originally I thought I could simply have an NSDictionary with the key being the weight, such as 35, and the value being the quantity.

Naturally I cannot store primitives in an NSDictionary or other Cocoa collection, so I have to encapsulate each integer in an NSNumber. However, the point of my modeling this weight set is so that I can simulate the use of certain weights. For example, if I use a 35 lbs. weight that takes 2 off (one for each side), so I have to go and edit the value for the 35 lbs. weight to reflect the fact that I have deducted 2 from the quantity.

This involves the tedious task of unboxing the NSNumber, converting back to a primitive, doing the math, and then re-boxing into an NSNumber and assigning that new result to the appropriate location in the NSDictionary. After searching around a bit, I confirmed my initial premonition that this was not a good idea.

So I have a couple questions. First of all, is there a better way of modeling a weight set aside from using a dictionary-style solution? If not, what is the suggested way to go about doing this? Do I have to leave the cocoa-realm and resort to using some sort of C++ STL template such as a map?

I have seen some information on NSDecimalNumber, should I just use that?

Like I said, I wouldn't be surprised if I am over-complicating this. I would really appreciate any help, thanks.

EDIT: I am beginning to think that the weight set 'definition' as described should indeed be immutable, as it is a definition after all. Then when I use a certain weight, I can add to some sort of tally. The thing is that the tally will also be some form of collection whose values I will be modifying (adding to), so that I can correlate it to the specific weight. So I guess I am in the same problem.

I think where I am trying to get at is creating a 'clone' so to speak of the weight set definition which I can easily modify (to simulate the usage of individual weights).

Sorry, I'm burned out.

+1  A: 

There's nothing wrong with storing your numbers in an NSDictionary! The question you referenced was referring to complicated, frequent math. Converting from NSNumber and back is slow compared to simple int addition, but is still super-fast compared to human perception. I think your dictionary idea is EDIT: not as good as Chuck's NSCountedSet idea. :)

andyvn22
Oh okay thanks man, that definitely clears that up. I guess it just feels weird to me, and tedious, having to convert back and forth each time. It just doesn't feel clean and readable. I knew that convention says to use NSNumber in dictionaries, but I was wondering if there were a better way. I think the best solution is Chuck's, but I appreciate your clearing this up. Upvoted.
Jorge Israel Peña
Blaenk: That's not quite was Louis was saying. His point was that storing in collections is about all NSNumbers are good for; what he didn't address is that storing numbers (in any form) in dictionaries is usually the wrong solution in the first place. As Chuck says, the correct solution for your purpose is an NSCountedSet.
Peter Hosey
+4  A: 

Storing this in a dictionary isn't a natural fit. I think the best approach would be to make a Weight class that represents the weights, and stick them in an NSCountedSet. You can get the individual kinds of Weight and the counts for each kind, and you can get the weight of the whole set with [weightSet valueForKeyPath:@"@sum.weightInPounds"] (assuming the Weights have a weightInPounds property that represents how heavy they are).

You could use NSNumbers in the NSCountedSet and sum them with @sum.integerValue if you wanted, but it seems a bit awkward to me. At any rate, NSCountedSet is definitely a more natural collection than an NSDictionary for storing — well, a counted set.

Chuck
Thanks man! Right after I posted this, on my way out I inevitably thought about making an individual Weight class to represent each weight. Doh! So simple and easy, I guess I was just too burned out to think about it. That's definitely the best solution. Thanks again. How embarrassing xD
Jorge Israel Peña
Hey. I tried the @sum.weight trick and it works, but since the NSCountedSet only maintains one copy of each unique object, it's only giving me the weight for a single weight even though I have, say, 4. I don't know if I'm being clear or not, do you know what I'm saying though? Is there any way to fix this? I mean I don't HAVE to use KVC but I'm just curious.
Jorge Israel Peña
@Blaenk: Are you putting NSNumbers in the counted set? If so, instead of using KVC, you'll have to iterate the counted set and multiply each element by its count. If you are using a weight class, as suggested, the KVC method will work provided you do not override hash and isEqual:
JeremyP
Of course, if you use a weight class, you don't need a counted set, you can use an ordinary one.
JeremyP
I'm using a weight class. The property exists too. But since the counted set contains only one copy, KVC just returns the information for those individual copies without taking into account the count for each object. So I guess I'll just iterate. What do you mean that I don't need a counted set, that I can just use an ordinary set if I have a Weight class? (which I do), just curious, since Chuck told me I /should/ use a counted set if I have a weight class. Thanks.
Jorge Israel Peña