Deleting a particular object in NSDictionary - ios

My Categories Dictionary is like this
"category": {
"position": 1,
"updated_at": "2012-11-21T11:02:14+05:30",
"is_default": false,
"name": "Ge",
"folders": [
{
How can i delete a particular Category object alone which has is_default as true?
I tried the following --
for(id obj in category )
{
if([obj isEqualToString:#"is_default"] && [[category objectForKey:#"is_default"] isEqualToNumber:#0])
{
but was unable to find a way to access the key of the particular category and hence delete it.

First thing first: You can not delete object from Dictionary(or Array Or Set) while Enumerating.
But it is not impossible.
Try this:
NSArray *keys = [category allKeys];
for(NSString *key in keys )
{
obj = [category objectForKey:key];
if([key isEqualToString:#"is_default"] && [[category objectForKey:#"is_default"] isEqualToNumber:#0])
{
[category removeObjectForKey:key]
}
}
Comment if you face any problem.
Al The Best.

You can get the keys (an object may be stored in the dictionary multiple times, using different keys) that your object is stored at like this:
NSArray *keys = [myDictionary allKeysForObject:obj];
Now that you have the key(s), it's easy to delete the object:
if (keys.count > 0) {
[myDictionary removeObjectForKey:keys.lastObject];
}
Searching through the values of a dictionary is a relatively slow operation, by the way. If you do this very often, a dictionary might not be the best data structure.

Related

Loop through NSArray of objects that has no id's - Objective C

I have an NSArray that looks like the following
[{
"Id":"456",
"Type":"Dog",
"Sound":"Bark",
},
{
"Id":"789",
"Type":"Cat",
"Sound":"Meow",
}]
I tried the following
for (id key in array) { // Doesn't work
NSLog(#"%#", key[#"Type"]);
}
and I tried
NSLog(#"%#", [array firstObject]); // Doesn't work
This doesn't work however because there is no id to access. I get an NSInvalidArgumentException for both. How would I successfully loop through the two objects that I have and print out the type?
It is a bit confusing, because you say:
I have an NSArray that looks like the following
[{
"Id":"456",
"Type":"Dog",
"Sound":"Bark",
},
{
"Id":"789",
"Type":"Cat",
"Sound":"Meow",
}]
but then, you also say:
NSLog(#"%#", [array firstObject]); // Doesn't work
Of course, you don't indicate what "Doesn't work" means... Does it throw an error? Does it output nothing? Does it output something, but not what you expect?
However, if you did have an array that "looks like that", then let's see what it actually is...
We can think of a Dictionary as:
{ key1:value1, key2:value2, key3:value3, etc... }
and we can think of an Array as:
[object1, object2, object3, etc...]
So, assuming your example data is structured like that in a valid NSArray, that means you have an Array of 2 Dictionary objects. If you want to output them to the console, you can do:
// log the first object in the array
NSLog(#"%#", [array firstObject]);
and the output should be a Dictionary:
{
Id = 456;
Sound = Bark;
Type = Dog;
}
You can also do:
// for each element (each Dictionary) in array, output the dictionary
for (NSDictionary *d in array) {
NSLog(#"%#", d);
}
resulting in:
...[1234:4321] {
Id = 456;
Sound = Bark;
Type = Dog;
}
...[1234:4321] {
Id = 789;
Sound = Meow;
Type = Cat;
}
and, finally:
// for each element (each Dictionary) in array
for (NSDictionary *d in array) {
// for each Key in each Dictionary
for (NSString *key in [d allKeys]) {
NSLog(#"%# - %#", key, d[key]);
}
}
which will give you:
...[1234:4321] Sound - Bark
...[1234:4321] Id - 456
...[1234:4321] Type - Dog
...[1234:4321] Sound - Meow
...[1234:4321] Id - 789
...[1234:4321] Type - Cat
Note that dictionaries are *un-ordered, so don't count on stepping through the keys in the same order each time.
Hope that makes sense. Of course, you still need to find out why you think you have a NSArray when you don't.

Create dictionary with dictionaries of arrays (sorted by a specific custom object property)?

The title may be confusing, apologies. Maybe someone can advise me on a more appropriate title.
I have a .json file structured as below.
"sections": [{
"title": "Locations",
"key": "location"
}],
"contacts": [{
"title": "Social Worker",
"name": "Mrs X",
"office": "xxxxxxxx",
"location": "Lisburn",
"department": "xxxxxxxx",
"telephone": "xxx xxxxxxxx"
},...
When parsing this, I create an array called contactsArray. I can then create AEContact objects from this array like so:
for (NSDictionary *contactDic in [contactsArray valueForKey:#"contacts"]) {
// Create AEContact objects
_contact = [[AEContact alloc] initWithDictionary:contactDic];
[contacts addObject:_contact];
}
self.contacts = [contacts copy];
In the self.contacts array, the value for the contact.location property is what I am interested in. I need to create separate arrays of related AEContact objects based on the location property, then map these to the location key in my contactArray dictionary
This is what I have tried so far:
NSMutableDictionary *locationsDic = [NSMutableDictionary new];
// Loop through contacts
for (int i = 0; i < self.contacts.count; i++) {
// Sort by location
if ([self.contacts[i] valueForKey:#"location"] == [[[contactsArray valueForKey:#"contacts"] objectAtIndex:i] valueForKey:#"location"]) {
[locationsDic setValue:self.contacts[i] forKey:[[[contactsArray valueForKey:#"contacts"] objectAtIndex:i] valueForKey:#"location"]];
}
}
And the output is:
{
Ballynahinch = "<AEContact: 0x15dda1fc0>";
Bangor = "<AEContact: 0x15dda2210>";
Lisburn = "<AEContact: 0x15dda1c70>";
...
}
When an AEContact object has the same location, it sets it as another key/value in the dictionary and overwrites the previous entry. What I need to happen is something like this:
{
Lisburn = "<AEContact: 0x15dda18f0>",
"<AEContact: 0x15dda18f0>",
"<AEContact: 0x15dda18f0>";
Bangor = "<AEContact: 0x15dda18f0>",
"<AEContact: 0x15dda18f0>",
"<AEContact: 0x15dda18f0>";
}
I'm not sure if the output should should/will look like the preview above, I can only assume as I have not yet achieved my goal. How can I create the related AEContact objects in an array and map them to location key in my locationsDic? Thanks.
The title (and the problem description) are a little tough to follow, but I think you're trying to index an array of (AEContact) objects by their location parameter.
We can clarify this just with some tighter naming and with a find-or-create pattern as we process the input.
NSDictionary *jsonResult = // the dictionary you begin with
NSArray *contactParams = jsonResult[#"contacts"];
NSMutableDictionary *contactsByLocation = [#{} mutableCopy];
for (NSDictionary *contactParam in contactParams) {
NSString *location = contactParam[#"location"];
// here's the important part: find the array of aecontacts in our indexed result, or
// create it if we don't find it
NSMutableArray *aeContacts = contactsByLocation[location];
if (!aeContacts) {
aeContacts = [#[] mutableCopy];
contactsByLocation[location] = aeContacts;
}
AEContact *aeContact = [[AEContact alloc] initWithDictionary:contactParam];
[aeContacts addObject:aeContact];
}
contactsByLocation will be what I think you're looking for.

Xcode - Getting object out of an array within an array

I have a JSON array(dictionary?) of objects that are themselves an array. I need to find a value within one of these arrays so that I can compare it later. Part of my JSON data:
[
{
"Name": "Exhibitor",
"Url": "api/congress/exhibitor",
"ResourceType": "Data",
"LastMod": 1389106977
},
{
"Name": "Workshop",
"Url": "api/congress/workshop",
"ResourceType": "Data",
"LastMod": 1389106977
},
{
"Name": "Speaker",
"Url": "api/congress/Speaker",
"ResourceType": "Data",
"LastMod": 1389106977
},
]
My method receives a table name as a parameter and returns a time stamp. How would I receive the time stamp (1389106977) for the table "workshop" for example? This seems so simple but I cannot work it out for 'nested' arrays/dictionaries.
Thanks,
edit:
This is the my code with trojanfoe's added to it.
NSError* localError;
NSMutableArray *syncDataArray = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
if (syncDataArray)
{
NSNumber *lastMod = nil;
for (NSDictionary *dict in syncDataArray)
{
NSLog(#"current table is: %#", dict[#"Name"]);
if ([tableName isEqualToString:dict[#"Name"]])
{
lastMod = dict[#"LastMod"];
//break;
}
}
NSLog(#"LastMod = %#", lastMod);
}
else
{
NSLog(#"syncDataArray is empty");
}
This works perfectly and makes sense
The JSON data looks like an array of dictionaries, so you can iterate over the array and test for the "Name" entry:
NSArray *jsonData = ...; // You have converted JSON to Objective-C objects already
NSNumber *lastMod = nul;
for (NSDictionary *dict in jsonData) {
if ([#"Workshop" isEqualToString:dict[#"Name"]]) {
lastMod = dict[#"LastMod"];
break;
}
}
if (lastMod) {
// You found it
}
(Note I am not certain the type of object used to store the "LastMod" object, so you might need to do some debugging to find out).
EDIT If you make extensive use of this data you should immediately convert the JSON data into an array of (custom) model objects, which will make it easier to manipulate the data as your app becomes more complex.
You have an array for dictionaries so it would look something like :
NSNumber *timestamp = [[JSON objectAtIndex:index] objectForKey:#"LastMod"];
NSNumber *timestamp = response[1][#"LastMod"];

Indexing an NSMutableDictiobary?

I have an NSMutableDictionary which holds objects of string type like this:
{
{
{"ID":"23"},
{"NAME":"Ted"}
},
{
{"ID":"46"},
{"NAME":"Karren"}
},
{
{"ID":"6"},
{"NAME":"Phillip"}
}
}
I need a way to access object with ID #x in an indexed manner.
Now, since the object with ID=46 is in index #1
I need a way to make the dictionary still have it's objects in their index as it is, but is it possible to add a key to that object?
Like:
"6":"{
{"ID":"6"},
{"NAME":"Phillip"}
}"
If possible to show some code.
Otherwise, how can I do that another way.
Thanks
What about using predicates ?
NSArray *resultArray = [[[myDictionary allValues] filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"ID == %#", #"6"]];
you retrieve all your dictionary values, and use a predicate to return a single element array with the value you were looking for
(code not tested but should work)
First of all you need to do something with the strucutre,
[
{
"ID": 23,
"Name": "Ted"
},
{
"ID": 46,
"Name": "Karen"
},
{
"ID": 6,
"Name": "Philip"
}
]
This would make your work a lot easier. You can search/sort it based on ID or Name easily.
//All users array
NSArray *users = ....
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"ID = %d",userID];
//Find User against a user id
NSDictionary *user = [[users filteredArrayUsingPredicate:predicate] lastObject];

ios-save nsdictionary in nsuserdefault

i want to save a nsdictionary have value null in nsuserdefault and don't need replace and delete value null
How?
My code -> impossible save in nsuserdefault
NSMutableArray * _itemsNames;
NSString * itemsFilename;
- (void) responseArray:(NSMutableArray *)array {
[_itemsNames setArray:array];
[spinner stopAnimating];
[_itemsNames writeToFile:itemsFilename atomically:YES];
NSMutableSet *filepathsSet = [[NSUserDefaults standardUserDefaults] objectForKey:#"test"];
[filepathsSet setByAddingObject:itemsFilename];
[[NSUserDefaults standardUserDefaults] setObject:filepathsSet forKey:#"test"];
}
The json is:(have value null)
({
ID:11,
name:21-12-2012,
des:"<null>",
url:
[
{
ID:1,
name: "<null>"
},
{
ID:2,
name:"<null>"
}
]
},
{
ID:12,
name:if i die young,
des:"<null>",
url:
[
{
ID:3,
name: "<null>"
},
{
ID:21,
name:"<null>"
}
]
})
If you have dictionary myDict
Then
[[NSUserDefaults standardUserDefaults] setObject:myDict forKey:#"MyDictionary"];
myDict will be saved only if it contains all objects that implements NSCoding
Regarding your null concept.
There is no need to save nil values in dictionary for a key.
If you try to get an object for a key and in dictionary there isn't any object related to that key then it will return nil. So no need to save null values
If you really need to store null values in NSDictionary use NSNull. Anyway you can just not store key with null value and then for [mydict objectForKey:#"keyWithNullValue"] you'll get nil.
But as I said if you really really want to store null use something like that:
NSSet *mySet = [NSSet setWithObjects:#{
#"ID":#(11),
#"name":#"21-12-2012",
#"des":[NSNull null],
#"url": #[#{
#"ID":#(1),
#"name": [NSNull null]
}, #{
#"ID":#(2),
#"name":[NSNull null]
}]
},#{
#"ID":#(12),
#"name":#"if i die young",
#"des":[NSNull null],
#"url": #[#{
#"ID":#(3),
#"name": [NSNull null]
}, #{
#"ID":#(21),
#"name":[NSNull null]
}]}, nil];
You mention saving dictionaries, but all you are showing is the JSON representation of an array of dictionaries.
You don't need to do anything strange, take the returned JSON data and turn it into an array and write the array to a plist. Turning it into a string and then trying to make a collection out of it is probably causing you the problems.

Resources