How to access NSMutableDictionary when the key looks like an int? - objective-c

I'm learning objective-c.
I tried to grab the entry of this NSMutableDictionary by using numbers as the key:
// [game analysisData] returns the Dictionary
NSMutableDictionary *data = [game analysisData];
NSLog(#"Data:\n%#", data);
// Try using "1" as the key.
id move = [data objectForKey:"1"];
NSLog(#"Move:\n%#", move);
But bad output:
move == (null).
So I can't access it with the string "1". Using an int doesn't work (compilation error).
Do you know how I can access the entries of this NSMutableDictionary?
Here's what the description looks like in FLEXTool:

You can use a NSNumber instead. You can write it like this :
NSNumber * key1 = #1;
NSNumber * key2 = #(1 + 1);
int intKey = 3;
NSNumber * key3 = #(intKey);
You can also do it with a string like this :
id move = [data objectForKey:#"1"]; // you forgot the #

Related

Convert NSString value to int

That may sound odd.
I got an NSString value NSString * numb = [self.dataDict valueForKey:#"id"]; and i know, that is it some kind of integer (for example, i need that integer to comparison - if val less or equal then something). I need to know what integer is it.
What i've tried:
NSNumber *numba = [self.dataDict valueForKey:#"id"];
NSLog output - numba is 2038735264
And actually that was 428.
is there any way to achieve the point? Thanks!
That is piece of responseObject:
(
{
id = 3;
dog = "\U041a\U0430\U043a\U043e\U0439-\U0442\U043e \U043c\U0443\U0434\U0430\U043a \U043d\U0430\U043a\U0440\U0443\U0442\U0438\U043b";
image = "cute_dog/116.jpg";
score = 586;
},
{
id = 115;
dog = "\U0422\U0430\U043d\U044f \U041a\U043b\U044e\U043a\U0432\U0438\U043d\U0430";
image = "cute_dog/115.jpg";
score = 481;
},
There are a number of methods you can use to convert an NSString to a number. What numeric type would you like?
NSString *string = self.dataDict[#"id"];
int intValue = string.intValue;
NSInteger integerValue = string.integerValue;
long long longLongValue = string.longLongValue;
Trying something like this.
NSNumber *numba = [NSNumber numberWithInt[self.dataDict valueForKey:#"id"]];
//For string
NSString *stringValue = [numba stringValue];
//For integer
NSInteger integer = [numba integerValue];

How to remove elements of NSDictionary

I have NSArray of NSDictionaries I need to extract 2 values or remove the values I don't need from the dictionary in the example below I need to remove id and NumberValue. any of you knows how can I do that?
Array: (
{
customerUS= {
DisplayName = "level";
InternalName = "Number 2";
NumberValue = 1;
id = xwrf
},
customerCAN= {
DisplayName = "PurchaseAmount";
InternalName = "Number 1";
NumberValue = 3500;
id = adf;
};
}
)
I'll really appreciate your help.
First thing, You can not remove/insert/update value in (immutable) NSDictionary/NSArray you need to convert NSDictionary/NSArray to (mutable) NSMutableDictionary/NSMutableArray.
such like
NSArray *myArr = ....;
NSMutableArray *newMutableArr = [myArr mutableCopy];
Then you can change in newMutableArr.
Such like
for(int i = 0 ; i < newMutableArr.count ; i ++)
{
[[newMutableArr objectAtIndex:i] removeObjectForKey:#"id"];
[[newMutableArr objectAtIndex:i] removeObjectForKey:#"NumberValue"];
}
EDITED:
Without Use of for loop and removeObjectForKey, if you have array of dictionary and both are mutable then you can also delete a key and its object from all elements of the array like this:
[newMutableArr makeObjectsPerformSelector:#selector(removeObjectForKey:) withObject:#"id"];
[newMutableArr makeObjectsPerformSelector:#selector(removeObjectForKey:) withObject:#"NumberValue"];
I would advice you to read Apple documents.
For modifying any Collection object after it is created, you need the mutable version.
For NSDictionary we have NSMutableDictionary. Read here.
We have a method for removing objects:
- (void)removeObjectForKey:(id)aKey
There are other methods as well. You can easily refer them in the above mentioned documentation.
Find out removeObjectForKey for deleting record from NSMutabledictionary.
removeObjectForKey pass the key value whatever you have like
all this are your key
DisplayName,
InternalName,
NumberValue,
id
do like this
removeObjectForKey:#"id";
First of all you have to convert the array to mutable array and then you can remove the key-value pairs from dictionary.
NSMutableArray *mutableArray = [yourArray mutableCopy];for(int i=0;i<mutableArray.count;i++){ NSMutableDictionary *outerDictionary = [mutableArray objectAtIndex:i]; for(NSString *key in outerDictionary.allKeys){ NSMutableDictionary *innerDictionary = [outerDictionary objectForKey:key]; [innerDictionary removeObjectForKey:#"id"]; [innerDictionary removeObjectForKey:#"NumberValue"]; }
}

Sort 4 ints, smallest to biggest

Suppose I have 4 integers.
int a = 4;
int b = 2;
int c = 4;
int d = 1;
How can I sort these integers from smallest to biggest. The output needs to be something like this: d, b, a, c Most methods of sorting only give me the value of the sorted integer. I need to know the name.
Edit: Well, I'm writing an AI algorithm. I have 4 ints that store direction priority. (If the AI comes into a wall, it chooses the next best direction). So, I need to find the lowest int, and if the AI can't move that way, I choose the second to lowest etc.
There appears to be some confusion here; in your example a is not the "name" for the value 4, it is the name of an integer variable which currently contains 4. In other words "a" is not part of the data of your program.
What I assume you mean is you have name/value pairs which you wish to sort using the value as key. A common way to do this is to define a type for your pair, create a collection, and sort the collection.
In plain C you can declare:
typedef struct
{
char *name;
int value;
} MyPair;
You can create an array of these and sort it using standard C functions for array sorting, using just the value field as the key.
In Objective-C you can declare a class for your pair:
#interface MyPair : NSObject
{
NSString *name;
int value;
}
// methods/properties
#end
You can create an NSMutableArray of instances of MyPair and then sort the array, again you just use the value property (or instance variable) when doing the comparisons for the sort algorithm.
There are other variations of course. Once sorted you can iterate through the sorted array and display the name field/property.
Here is an objective-c approach. Unfortunately, you will not have the fun of writing the AI portion, the sorting is built into the libraries already.
int north = 1, south = 3, east = 2, west =4;
NSDictionary * nDict = [NSDictionary dictionaryWithObjectsAndKeys:#"north", #"name", [NSNumber numberWithInt:north], #"value", nil];
NSDictionary * sDict = [NSDictionary dictionaryWithObjectsAndKeys:#"south", #"name", [NSNumber numberWithInt:south], #"value", nil];
NSDictionary * eDict = [NSDictionary dictionaryWithObjectsAndKeys:#"east", #"name", [NSNumber numberWithInt:east], #"value", nil];
NSDictionary * wDict = [NSDictionary dictionaryWithObjectsAndKeys:#"west", #"name", [NSNumber numberWithInt:west], #"value", nil];
NSArray * toBeSorted = [NSArray arrayWithObjects:nDict,sDict,eDict,wDict,nil];
NSArray * sortDescriptors = [NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:#"value" ascending:NO]];
NSArray * sorted = [toBeSorted sortedArrayUsingDescriptors:sortDescriptors];
NSLog(#"sorted %#", sorted);
Output
2012-01-23 19:50:21.079 TestEnvironment[19792:207] sorted (
{
name = west;
value = 4;
},
{
name = south;
value = 3;
},
{
name = east;
value = 2;
},
{
name = north;
value = 1;
}
)
Now you can check the highest priority by
NSString * highestPriority = [[sorted objectAtIndex:0] objectForKey:#"name"];
Now you have some classes you can look up (NSArray, NSDictionary, NSSortDescriptor, NSNumber)
You've tagged this Objective-C, but you haven't written anything that suggests using Objective-C. If you want to use Objective-C, I'd put the elements into an NSMutableArray (they'll need to be converted to NSNumbers to do that), and have the array sort them, as seen here.
If you just want to put them into a straight C array, you could sort them using heapsort (), qsort(), or mergesort().

fast enumeration for NSDictionary instance ordered by the key

Overview
I am using fast enumeration to iterate through an NSDictionary instance
I expected the NSDictionary instance to be enumerated based on the ascending order of the key but that doesn't seem to be the case
What I want to do:
I want to be able iterate through the NSDictionary instance in the ascending order of the key using fast enumeration
Note: Pls see expected output vs actual output
Questions
Am i making a mistake with my implementation ?
Does NSDictionary's fast enumeration guarantee ordering based on keys ?
If not then is there a work around for this and yet use fast enumeration ?
Example
#import<Foundation/Foundation.h>
int main()
{
system("clear");
NSDictionary *d1 = nil;
#autoreleasepool
{
d1 = [[NSDictionary alloc] initWithObjectsAndKeys: #"AAA", [NSNumber numberWithInt:10],
#"BBB", [NSNumber numberWithInt:20],
#"CCC", [NSNumber numberWithInt:30],
nil];
}
for(NSNumber* n1 in d1) //I expected fast enumeration for NSDictionary to be based on the
//ascending order of the key but that doesn't seem to be the case
{
printf("key = %p"
"\t [key intValue] = %i"
"\t value = %s\n",
n1,
[n1 intValue],
[[d1 objectForKey:n1] UTF8String]);
}
return(0);
}
Expected Output
key = 0xa83 [key intValue] = 10 value = AAA
key = 0x1483 [key intValue] = 20 value = BBB
key = 0x1e83 [key intValue] = 30 value = CCC
Actual Output
key = 0x1e83 [key intValue] = 30 value = CCC
key = 0xa83 [key intValue] = 10 value = AAA
key = 0x1483 [key intValue] = 20 value = BBB
for (NSString *key in [[d1 allKeys] sortedArrayUsingSelector:#selector(compare:)])
{
id value = [d1 valueForKey:key];
...
}
No your implementation is correct.
NSDictionary fast enumeration does not guarantee sorting (and it will not output anything in order because of implementation as hashed container).
No, you have to sort it yourself.
There is no guaranties about the order in which you will receive your object.
allKeys
Returns a new array containing the dictionary’s keys.
- (NSArray *)allKeys
Return Value
A new array containing the dictionary’s keys, or an empty array if the dictionary has no entries.
Discussion
The order of the elements in the array is not defined.
So my suggestion is, if your dictionary doesn't change often, cache an NSArray with the key in the order you want them.
If your dictionary often change, you may have to sort allKeys when you need them.

Simple NSInteger and NSMutableArray question

I'm trying to access an array using another array integer value as an index.
NSInteger index=[appDelegate.randomRiddles objectAtIndex:appDelegate.randomRiddlesCounter];
int i = index;
questionText.text = [[appDelegate.currentRiddlesContent objectAtIndex:i] objectForKey:#"question"];
//where appDelegate.randomRiddlesCounter is an NSInteger and appDelegate.randomRiddles is a NSMutableArray
However I'm getting incompatible pointer to int conversion warning. How can I fix this above code? The warning I get is coming from the first line.
Try:
NSNumber *index = [appDelegate.randomRiddles objectAtIndex: appDelegate.randomRiddlesCounter];
int i = [index intValue];
questionText.text = [[appDelegate.currentRiddlesContent objectAtIndex: i] objectForKey: #"question"];
NSInteger is an integral type, not an object.
Try this:
int i = [index intValue];
An NSArray like object can only store Objective-C object pointers (i.e. everything that you can assign to an id)
With objectAtIndex you get the object, with indexOfObject:(id)anObject you get the corresponding index.
These two instructions are both valid:
id bla = [appDelegate.randomRiddles objectAtIndex:appDelegate.randomRiddlesCounter];
NSInteger index = [appDelegate.randomRiddles indexOfObject:myObject];
The second assumes that myObject is at least of type id
So you try to convert a pointer to an int. Therefore the warning is issued.