Objective C NSMutableDictionary - objective-c

I have a question about NSMutableDictionary,
Let's say I have two set of NSMutableDictionary:
NSMutableDictionary *oddNumber
NSMutableDictionary *randomNumber
Is there a function to check value of randomNumber is SUBSET of value of oddNumber or not?

You can do something like this,
NSMutableDictionary *oddNumber;
NSMutableDictionary *randomNumber;
// Create arrays
NSArray *arroddNumber = [oddNumber allValues];
NSArray *arrrandomNumber = [oddNumber allValues];
// Turn the arrays into sets and intersect the two sets
NSMutableSet *oddNumberSet = [NSMutableSet setWithArray:arroddNumber];
NSMutableSet *randomNumbersSet = [NSMutableSet setWithArray:arrrandomNumber];
[oddNumberSet intersectSet:randomNumbersSet];
// The Values present in both arrays
NSLog(#"Common Values : %#", oddNumberSet);

You could get the values for each dictionary using the values method. This returns an array. You could then convert these arrays to sets, which have methods to check if one set is a subset of another.

Look at the values that you have. Make sure they have an isEqual: method and a hash method, so you can add them to a set. Create an NSSet with all values of the second dictionary, then iterate through the first dictionary and check which values are in the set.
Note that creating a set with N values takes O (N) time if the values have a decent hash function, and looking up a value in a set is constant time.

Short:
BOOL isSubset = [[oddNumber dictionaryWithValuesForKeys:[randomNumber allKeys]] isEqualToDictionary:randomNumber]
or faster:
__block BOOL isSubset = YES;
[randomNumber enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop){
id value = [oddNumber objectForKey:key];
if (!value || ![value isEqual:obj]) {
isSubset = NO;
*stop = YES;
}
}];

Related

How to sum all values in NSMutableDictionary with the same key?

I have a NSMutableDictionary in my objective c class with different pair keys values.
({Name=John; date=20070506; type=5; value= 125;},
{Name=Tracy; date=20040506; type=2; value = 237; },
{Name=Tracy; date=20040506; type=5; value = 124; },
...)
I can sum all values with the next code, but I can't get this in the same object in NSMutableDictionary.
NSNumber *amountSum = [CATransaction valueForKeyPath:#"#sum.value"];
How could I sum the values for all objects with the same type and show this like one unique object? For example:
({Name=John; date=20070506; type=5; value= 249;},
{Name=Tracy; date=20040506; type=2; value = 237; },
...)
Could I use a collection operator like this: Collections operators to do this??
thanks!
Get all the values for that valueForKey, so [Yourarray valueForKey:#"keyName"] will give you each value and finally you can loop over and sum all the values in array.
int total=0;
NSMutableDictionary *yourMutableDict=[[NSMutableDictionary alloc] init];
for (;;)
{
int value=[[Yourarray objectAtindex:i] valueForKey:#"keyName"];
total=total+value;
}
[yourMutableDict setValue:[NSNumber numberWithInteger:total] forKey:#"mySUM"];
NSLog(#"%#",[yourMutableDict objectForKey:#"mySUM"]);

Check duplicate property values of objects in NSArray

I have an NSArray containing objects with a size property.
How can I check if the NSArray has two objects with the same value for size?
Can I do something like:
int i = 0;
for (id item1 in myArray) {
NSDecimalNumber *size1 = [item1 size];
for (id item2 in myArray) {
NSDecimalNumber *size2 = [item2 size];
if ([size1 isEqual:size2]) {
i ++;
}
}
}
if (i > [myArray count]) {
NSLog(#"Duplicate Sizes Exist");
}
Or is there an easier way?
Try this code:
NSSet *myset = [NSSet setWithArray:[myarray valueForKey:#"size"]];
int duplicatesCount = [myarray count] - [myset count];
size here is the object property.
Use NSCountedSet. then add all your objects to the counted set, and use the countForObject: method to find out how often each object appears in your array.
You can check this link also how-to-find-duplicate-values-in-arrays
Hope it helps you
Probably simplest is to sort the array based on the size field and then step through the sorted list looking for adjacent dupes.
You could also "wrap" each object in one that exports the size as its key and use a set. But that's a lot of extra allocations.
But if you only want to know if dupes exist, and not which ones they are, create an NSNumber for each object's size and insert the NSNumbers in a set. The final size will tell you how many dupes.
NSArray *cleanedArray = [[NSSet setWithArray:yourArraywithDuplicatesObjects ] allObjects];
Use Sets this will remove all duplicates objects.Will return NSArrayNSCountedSet and use countForObject: method to find out how often each object appears how many times.

NSSet: return an NSArray of objects sorted by a list of strings on certain property of each object?

I have an NSSet of objects.
Each object in the set is an instance of MyObject with a property called name.
I have another NSArray called nameIndexes which contains name values.
I would like to have a function that takes the NSSet and returns a sorted array sorted using the name property based on its position in the nameIndexes array.
Edit:
Sorry for my misleading, here is an example:
I have a set of MyObject(may not be in the same order):
MyObject1 {name:#"A"}
MyObject2 {name:#"B"}
MyObject3 {name:#"C"}
I have another array of names:
{"B", "A", "C"}
I want an NSArray of:
{MyObject2, MyObject1, MyObject3}
NSSet *set = //your set.
NSArray *nameIndexes = //the array of names for sorting.
NSArray *result = [[set allObjects] sortedArrayUsingComparator:^NSComparisonResult(MyObject *obj1, MyObject *obj2) {
int index1 = [nameIndexes indexOfObject:obj1.name];
int index2 = [nameIndexes indexOfObject:obj2.name];
return [[NSNumber numberWithInt:index1] compare:[NSNumber numberWithInt:index2]];
}];
Not 100% certain what you are asking but this will sort take the set of names and turn it into a sorted array sorted based on the index of the names in a second array.
After edit
Edit... ok, so your edit completely changed the question. Anyway, from the edit you can just do...
NSArray *result = [[set allObjects] sortedArrayUsingDescriptors:[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:"name" ascending:YES]]];
This will take the set and return a sorted array sorted by the name property of the objects in alphabetical order.

NSMutableArray contains Objects

I have to check whether an NSMutableArray contains an object multiple times (for e.g. the array contains 1,2,3,1,4), I want to know how many times 1 is present in the array. I am aware of containsObject: but how to use it for this kind of check?
NSCountedSet may help as you want to track how many times a duplicate value occurs.
http://developer.apple.com/library/ios/#documentation/Cocoa/Reference/Foundation/Classes/NSCountedSet_Class/Reference/Reference.html#//apple_ref/occ/cl/NSCountedSet
A quick way would be to convert it to an NSSet and then back to an array. NSSets cannot contain duplicates. Alternatively copy the values one by one into a new array using a loop, and each time check that the new array does not contain a copy of the object before adding it.
It depends on your object types, but if they can be used as keys for an NSDictionary, I would create an NSMutableDictionary that points to NSNumber objects containing counts for each object instance. Something like:
NSArray *array = whatever;
NSMutableDictionary *d = [NSMutableDictionary dictionaryWithCapacity:array.count];
for ( id obj in array )
{
NSNumber *number = [d objectForKey:obj];
if ( number == nil )
{
[d setObject:[NSNumber numberWithInt:1] forKey:obj];
}
else
{
[d setObject:[NSNumber numberWithInt:([number intValue]+1) forKey:obj];
}
}
At the end of this code, you are left with an NSDictionary where the keys are your original objects and the values are NSNumbers that contain the number of times that key exists in the original.

dynamic naming of fields in nsmutable array?

I hope i can explain this clearly.
I have a NSMutableArray * myMut.
I have user input in the form of an NSString * anyoldString.
I have user input of some numeric values stored in the variable someNumber;
As users input their string and values, I want to update myMut, and name the fields anyoldString
like this: myMut.anyoldString=someNumber;
depending on the user's input, the name will be different of course
i'm new to objective c.
in Matlab, I would do this:
myMut.(anyoldString)=someNumer.
I know that's too easy for objective c! but any fast way to do this??
You'll probably want to do something like so:
NSMutableDictionary *myMutableDictionary; // A mutable **dictionary**, not an array!
NSInteger someNumber; // filled by the number
NSString *key; // filled by anyOldString
[myMutableDictionary setObject:[NSNumber numberWithInteger:someNumber] forKey:key];
NSArray and friends aren't associative; but indexed. What you want is NSDictionary and friends; your friendly neighborhood key-value mapping!
Edit: For funsies; getting someNumber back out, given anyOldString:
NSMutableDictionary *myMutableDictionary; // The same dictionary as above
NSInteger someNumber; // out number
NSString *key; // filled by anyOldString
NSNumber *storedNumber = [myMutableDictionary objectForKey:key];
if (storedNumber) {
someNumber = [storedNumber integerValue];
} else {
someNumber = APPLICATION_APPROPRIATE_DEFAULT_VALUE;
}