NSMutableArray with NSDictionary to NSMutableDictionary - ios

Here is the situation:
I have a request on AFNetworking that retrieves me a JSON with an NSArray.
My goal is to mutate the NSDictionaries inside it. I already made a mutableCopy of the array, but I want to know if I can easily mutate all the content. Will I have to iterate through the array manually?

NSJSONSerialization has options to allow you to control the mutability of the resulting data structure. Just pass the appropriate ones (probably NSJSONReadingMutableContainers) and there you go.

You cannot mutate NSDictionary, just because only NSMutableDictionary has method setObject:forKey:
So you should create mutableCopy of each dictionary and empty mutable array. Then with a forloop fill that array. Your code should be so:
- (NSMutableArray *)mutatedArrayFromArray:(NSArray *)array
{
NSMutableArray *resultArray = [NSMutableArray new];
if([array count] > 0)
{
for(int i = 0; i < count; i++)
{
NSMutableDictionary *mutatedItem = [[array objectAtIndex:i] mutableCopy];
[resultArray addObject:mutatedItem];
[mutatedItem release]; // only with ARC disabled
}
}
return [result autorelease]; // if ARC enabled : return result;
}

Related

Compare the unique index value with another array in objective C

There is an array having same objects in single array , i need to compare these array’s index with another array.. Give me a help.
Something like:
NSMutableArray *latArray =
[NSMutableArray arrayWithObjects:#“43.20,#“43.23”,#“43.24”,#“43.20”,nil];
NSMutableArray *lngArray =
[NSMutableArray arrayWithObjects:#“76.90”,#“76.94”,#“76.92”,#“76.90”,nil];
NSMutableArray *imagesArray =
[[NSMutableArray alloc] initWithObjects:#"1.jpg", #"2.jpg”,#“3.jpg”,#“4.jpg”,nil];
resultResult = #"1.jpg", #“4.jpg” // because the index 0 and index 3 same values in both array.
I would wrap your coordinates into location objects and use them as the keys in a dictionary. This would allow to check for duplicate coordinates, like this:
NSMutableDictionary *results = [[NSMutableDictionary alloc] init];
for (int i = 0; i < [imagesArray count]; i++)
{
// Wrap coordinates into a NSValue object
// (CLLocationCoordinate2D is a C-struct that cannot be used as a dictionary key)
// (CLLocation also does not implement required methods to be usable as a dictionary key)
NSValue *loc = [NSValue valueWithMKCoordinate:CLLocationCoordinate2DMake(
((NSNumber)[latArray objectAtIndex:i]).doubleValue,
((double)[lngArray objectAtIndex:i]).doubleValue)];
// 1. If you only want the first occurrence of a specific location, use this:
if ([results objectForKey:loc] == nil)
{
[results setObject:[imagesArray objectAtIndex:i] forKey:loc];
}
// 2. Or, if you want the last occurrence of a specific location, use this:
[results setObject:[imagesArray objectAtIndex:i] forKey:loc];
}
I think you are trying the check for the same objects in an array. If so do the following.
for(int i=0;i<yourarray.count;i++)
{
NSString *yourstring=[yourarray objectatindex:i];
for(int k=0;k<yourarray.count;k++)
{
if(i!=k)
{
NSString *yourstring2=[yourarray objectatindex:k];
if([yourstring isEqualtostring yourstring2])
{
//now you got equal objects. do what ever you want here
}
}
}
}

Want to get key value from NSDictionary

I want to get all key values in an array. Here I used the keyword allKeysForObject. While using allKeysForObject, I got value within parenthesis. I want to store value without parenthesis.
Here is my code:
dict = [[NSMutableDictionary alloc]init];
[dict setValue:#"Hai" forKey:#"1"];
[dict setValue:#"lrd" forKey:#"2"];
NSArray *keys = [dict allKeys];
NSMutableArray *countryArray = [[NSMutableArray alloc]init];
NSMutableArray *keyObjects = [[NSMutableArray alloc]init];
for(NSString* key in keys) {
NSString *obj = [dict objectForKey:key];
[countryArray addObject:obj];
}
for (int i =0; i < [countryArray count]; i++) {
[keyObjects addObject:[dict allKeysForObject: [countryArray objectAtIndex:i]]];
}
NSLog(#"%#",[keyObjects objectAtIndex:0]);
The NSLog value is:
2013-11-28 17:12:48.400 Help[6775:c07] (
1
)
Thanks in advance.
Replace:
NSLog(#"%#",[keyObjects objectAtIndex:0]);
With:
NSLog(#"%#",[keyObjects objectAtIndex:0][0]);
You are storing in keyObjects the value returned by allKeysForObject: which is a NSArray.
You will get all values in an NSDictionary using [dict allValues]. you dont need to manually iterate the array
dict = [[NSMutableDictionary alloc]init];
[dict setValue:#"Hai" forKey:#"1"];
[dict setValue:#"lrd" forKey:#"2"];
NSMutableArray *countryArray = [[dict allValues] mutableCopy];
NSMutableArray *keyObjects = [[NSMutableArray alloc]init];
for (int i =0; i < [countryArray count]; i++) {
[keyObjects addObject:[dict allKeysForObject: [countryArray objectAtIndex:i]]];
}
NSLog(#"%#",[keyObjects objectAtIndex:0][0]);
Instead of using loop for getting all key values from NSDictionary use - (NSArray *)allKeys;
method to do that. It is always good to use given methods than writing our own code to achieve the same.
so replace of the for loop with following code...
keyObjects = [[dict allKeys]mutableCopy]; // mutableCopy because I think you want it mutable as your array is mutable.
EDIT
AFA your code concern, your are getting parenthesis because you are storing all keys in keyObjects array as array, that why you can see those parenthesis out there in you log statement. and this is because allKeysForObject method returns array of keys related to given object.
and if you want it to be done in your way here it is...
for (int i =0; i < [countryArray count]; i++) {
[keyObjects addObject:[dict allKeysForObject: [[countryArray objectAtIndex:i]0]]];
}
While NSLog-ing:
Whenever you see (...) it is array.
Whenever you see {...} it is dictionary.
So in your case it is shown as (1) so this is an array with one object.
Hence you need to do through one level down to retrieve it.
NSLog(#"%#",[[keyObjects objectAtIndex:0] objectAtIndex:0]); //or
NSLog(#"%#",[keyObjects objectAtIndex:0][0]);

a faster way to mutate an Array of NSMutableDictionaries

based on the fact that you cannot edit mutable Collections while enumerating them, this is the best solution i could come up with to edit a Array of NSMutableDictionaries:
__block NSMutableDictionary *tempDict = [NSMutableDictionary dictionaryWithCapacity:1];
__block NSUInteger idx;
[_myArray enumerateObjectsUsingBlock:^(NSMutableDictionary* obj,
NSUInteger indx, BOOL *stop) {
if (// some condition is met) {
tempDict = [obj mutableCopy];
idx = indx;
}
}];
[tempDict setObject:[NSNumber numberWithInt:thisQueryResults] forKey:#"resultsNum"];
[_myArray replaceObjectAtIndex:idx withObject:rowSelected];
this seems way too complicated (even for a language like obj-c).. and since it's involving two data types (NSMutableArray and NSMutableDictionary), it doesn't seem like I can cleanly put them into a category.. advice?
update: one comment asked why do I create a mutablecopy (as opposed to just a copy.. since it's copying a mutable object)..
suppose I just used copy.. if i put a break on tempDict this is what I get:
// tempDict = [obj copy]
po tempDict
$0 = 0x0b28cc10 <__NSArrayI 0xb28cc10>(
1
)
// tempDict = [obj mutableCopy]
po tempDict
$0 = 0x0b28cc10 <__NSArrayM 0xb28cc10>( //notice the M in __NSArrayM as opposed to I above
1
)
in case of copy.. if I follow it with a line like this:
[tempDict setObject:[NSNumber numberWithInt:thisQueryResults] forKey:#"resultsNum"];
I get this error:
[__NSDictionaryI setObject:forKey:]: unrecognized selector sent to instance 0xb245100
I get the same above error with this code:
for (NSUInteger idx = 0; idx < [_myMutableArray count]; idx++) {
NSMutableDictionary* myMutableDict = _myMutableArray[idx];
[myMutableDict setObject:obj forKey:key];
}
update 2:
the origin of the problem was instantiating non mutable arrays and dictionaries.. I'm new to the whole new obj-c literals, so I didn't know that to create a NSMutableArray and NSDictionary, you gotta do this, respectively:
[#[..] mutableCopy]
[#{..} mutableCopy]
So in your case, I don't quite follow why you call tempDict = [obj mutableCopy]; when from the conditions you write the dictionary is already writable.
You can use several tricks. Like using
for (NSUInteger idx = 0; idx < _myArray.count: idx++_ {
NSMutableDictionary *obj = _myArray[idx];
// modify
}
For NSDictionaries you can get allKeys and iterate over that copy. This is a bit slower than using fast enumeration, but still faster than doing workarounds like boxing integers to replace later :)
In your case you are NOT modifying the array at all only the dictionaries within the array. There are no contstraits on how you modify the objects within the array. Here is a bit of equivalent code:
for (NSMutableDictionary *dict in _myArray) {
if (someCondition)
[dict setObject:[NSNumber numberWithInt:thisQueryResults] forKey:#"resultsNum"]
}
You would have a problem if you absolutely needed to replace the object in your array. In that case, if the array is not huge I would suggest the same as #Markus. Iterate over a copy and modify the original.
Maybe you can use KVC and do :
NSArray<NSMutableDictionary *> *result = [[_myArray filteredArrayUsingPredicate:[NSPredicate withFormat:#"{YOUR CONDITION}"]] valueForKey:#"mutableCopy"];

How can I move the values in NSMutableArray to NSArray

I have an array of recommendedcar IDs, and another array of allcar IDs. From this, I have to take the recommendedcar images. First, I check whether the recommended carid is in my allcar id; if it is, I select the corresponding car images, and store them into NSArray.
This is the code I am using.
for (int i=0;i<[listOfCarId count];i++) {
for (int j=0;j<[_allCarID count];j++) {
tempAllCarId=[_allCarID objectAtIndex:j];
tempRecommendedCarId=[listOfCarId objectAtIndex:i];
if ([tempRecommendedCarId isEqualToString:tempAllCarId]) {
_recommendedCarImage=[_allCarImages objectAtIndex:j];
NSLog(#"finalImage%#",_recommendedCarImage);
}
}
}
_recommendedcarImage is NSMUtableArray; I want a NSArray. How can I convert it to a NSArray?
How can i replace the "_recommendedCarImage " with an NSArray?? Currently _recommendedCarImage is a mutable array.
Polymorphism. Since NSMutableArray is a subclass of NSArray, you can use it anywhere an NSArray is expected. You don't have to do anything.
Now its working,What i did is , I just copy the contents of Mutable array to NSarray
recommendedArray=[_recommendedCarImage copy];
An NSMutableArray is an NSArray already (as it's a subclass of NSArray), still you can do:
NSArray *array = [NSArray arrayWithArray:mutableArray];

NSMutableDictionary -- using allKeysforObject not retrieving array values

NSMutableDictionary *expense_ArrContents = [[NSMutableDictionary alloc]init];
for (int i = 1; i<=4; i++) {
NSMutableArray *current_row = [NSMutableArray arrayWithObjects:#"payer_id",#"Expense_Type_id",#"Category_Id",#"SubCategory_Id",nil];
[expense_ArrContents setObject:current_row forKey: [NSNumber numberWithInt:i]];
}
NSArray *newArray = [expense_ArrContents allKeysForObject:#"payer_id"];
NSLog(#"%#",[newArray description]);
i want to get the list of key values containing the particular object which is in the array of values stored in nsmutabledictionary for a particular key.
In the line where you get all the keys ([expense_ArrContents allKeysForObject:#"payer_id"];) you actually get keys for an object that is not in any of the array's items. This #"player_id" is different object than the #"player_id" you added in current_row. In fact, maybe all of your rows have different #"player_id" objects (except if the compiler has made some optimization - maybe it threats that same string literal as one object instead of creating new object for each iteration).
Try creating an NSString object for the #"player_id" which you add to the current_row and then get all the keys for that same object:
NSString* playerId = #"player_id";
for(){
NSMutableArray *current_row = [NSMutableArray arrayWithObjects: playerId,...];
...
}
NSArray *newArray = [expense_ArrContents allKeysForObject:playerId];
Your NSArray *newArray = [expense_ArrContents allKeysForObject:#"payer_id"]; will not return any value because in expense_ArrContents there is no such key(#"payer_id"), instead there are keys like 1,2,3 etc.What is your requirement?Want to see what all keys are there in expense_ArrContents just log
NSArray*keys=[expense_ArrContents allKeys];
Try this :
NSMutableArray *array_key=[[NSMutableArray alloc]init];
for (NSString *key in expense_ArrContents) {
if ([[expense_ArrContents objectForKey:key] containsObject:#"payer_id"]) {
[array_key addObject:key];
}
}

Resources