Parse nested JSON Object in Objective-C - objective-c

Perhaps I am over-thinking or confusing myself, but my head is stuck in a loop over this and I cannot break out.
I have a a JSON of the format: (Validated at http://jsonformatter.curiousconcept.com/)
{
id: 1,
sections: "5",
total: "10",
result: {
3: 00PM: [
{
name: "Anurag",
status: "Web"
},
{
name: "Anurag2",
status: "Web2"
}
],
5: 00PM: [
{
name: "Anurag",
status: "Seated"
}
],
6: 00PM: [
{
name: "Anurag4",
status: "Web4"
},
{
name: "Anurag5",
status: "Web5"
},
{
name: "Anurag6",
status: "Web6"
},
{
name: "Anurag7",
status: "Web7"
}
]
}
}
I have this so far:
NSDictionary *dict = [response JSONValue];
NSDictionary *results = [dict objectForKey:#"result"];
NSInteger num_results = [[dict valueForKey:#"total"] intValue];
NSInteger num_sections = [[dict valueForKey:#"sections"] intValue];
NSMutableArray *sections = [[NSMutableArray alloc] initWithCapacity:num_sections];
NSMutableArray *objarr = [[NSMutableArray alloc] initWithCapacity:num_results];
NSMutableArray *obj= [[NSMutableArray alloc] initWithCapacity:num_sections];
NSMutableArray *temp = [[NSMutableArray alloc] initWithCapacity:num_results];
for (NSString* key in results) {
NSLog(#"Key: %#", key); // prints out 3:00 PM...5:00 PM etc...
[obj addObject:[results objectForKey:key]]; // nested objects within each key are saved in the array
NSLog(#"Object 1: %#", obj);
}
for (int i = 0; i < [obj count]; i++) {
//NSLog(#"Object 2: %#", [obj objectAtIndex:i]);
[temp addObject:[obj objectAtIndex:i]]; // I take each object from previous array and save it in a temp array
for (int i = 0; i < num_results; i++) {
NSLog(#"Object 3: %#", [temp objectAtIndex:i]);
**[objarr addObject:[temp objectAtIndex:i]]; // I want to extract the object within the object but cannot get it to work**
}
}
I am able to make an array of objects within each of the 3 keys inside results. But I am not able to get each of the objects inside them as a separate object and save them in an array.
For example, in an NSArray I have:
Object 3: (
{
name = "Anurag ";
status = Web;
},
{
name = "Anurag ";
status = Web;
}
)
How can I get the two objects inside this object and save them both in an array?
I guess the main issue is I cannot refer to a key name to get the individual object.

You can use the following code,
NSDictionary *json = [response JSONValue];
// Get the objects you want
NSArray *items = [json valueForKeyPath:#"result.6: 00PM"];
This will return an NSArray with the objects for the key 6: 00PM
Please check this link too.

You are redefining int i in your second for loop. Try something like
for(int j = 0; j < num_results; j++)

[temp addObject:[obj objectAtIndex:i]]; // I take each object from previous array and save it in a temp array
This is useless motion. You're effectively just copying the obj array to the temp array -- no value added.

Related

Parse NSDictionary in NSArray created from JSON in Objective-C

I'm trying to get information out of this Dictionary that was created from a JSON string. The JSON string is returned from the server and is put in a dictionary. That dictionary is passed to myMethod that is suppose to break it down so I can get the information that each record contains.
The "Recordset" is an Array. The Record is also an array of dictionaries.
How do I get to the dictionaries? I keep getting NSDictionaryM objectAtIndex: unrecognized selector sent to instance
Recordset = (
{
Record = (
{
MODMAKlMakeKey = 1112;
MODlModelKey = 1691;
MODvc50Name = "10/12 Series 2";
},
{
MODMAKlMakeKey = 1112;
MODlModelKey = 1687;
MODvc50Name = "10/4";
},
{
MODMAKlMakeKey = 1112;
MODlModelKey = 1686;
MODvc50Name = "10/6";
},
etc .. etc... ( about 100 records )
Here is what I have
- (void) myMethod : (NSDictionary*) dictionary {
//INITIAL
NSArray * arrRecordSet = [dictionary objectForKey:#"Recordset"];
NSArray * arrRecord = [arrRecordSet objectAtIndex:0];
NSDictionary * theRecord = [NSDictionary dictionaryWithObjects:arrRecord forKeys:[arrRecord objectAtIndex:0]];
for (int i = 0; i < arrRecord.count; i++) {
NSLog(#"MODMAKlMakeKey: %#", [theRecord objectForKey:#"MODMAKlMakeKey"]);
}
}
Try this
NSArray * arrRecord = [arrRecordSet objectForKey:#"Record"];
Try to check first if the return of [dictionary objectForKey:#"Recordset"] is really a dictionary or an array.
To do this:
if([[dictionary objectForKey:#"Recordset"] isKindOfClass:[NSArray class]]) {
//object is array
}
else if ([[dictionary objectForKey:#"Recordset"] isKindOfClass:[NSDictionary class]]) {
//object is dictionary
}

Adding objects to an NSmutableArray from a C Array

I have an NSmutable array and I am adding some strings present in the C array to it. By using this method
if (!self.arrayOfVariableNames) {
self.arrayOfVariableNames = [[NSMutableArray alloc] init];
for (int i = 0; i< cols; i++) {
[self.arrayOfVariableNames addObject:[NSString stringWithCString:cArrayOfVariableNames[i] encoding:NSUTF8StringEncoding ]];
}
}
else{
[self.arrayOfVariableNames removeAllObjects];
for (int i = 0; i< cols; i++) {
[self.arrayOfVariableNames addObject:[NSString stringWithCString:cArrayOfVariableNames[i] encoding:NSUTF8StringEncoding ]];
}
}
Does this method ensure that the objects in the NSmutableArray won't be deallocated when the C array is taken out of memory?
if this array arrayOfVariableNames is becoming Null, then the problem is with the initialisation of the array. Please try to use Lazy loading by doing this:
- (NSArray*)arrayOfVariableNames {
if (!_arrayOfVariableNames) {
_arrayOfVariableNames = [[NSMutableArray alloc] init]; //initialise the array if needed
}
return _arrayOfVariableNames; //else return the already initialized array
}
and please comment out this line in your code: self.arrayOfVariableNames = [[NSMutableArray alloc] init];
****EDIT****
Please find the update code in https://docs.google.com/file/d/0BybTW7Dwp2_vdHhQN1p1UzExdTA/edit?pli=1. Have a look at it.
Yes. NSArray retains anything in it.
But you should stop chaining your NSString creation and instead creat a string a line before adding it to the array. Then check for nil.
Only add it to the array if it is not nil.
Do code defensively.
arrayOfVariableNames will not change when the C array get deallocated.
Make sure that your arrayOfVariableNames variable is strong.
#property (nonatomic, strong) NSMutableArray *arrayOfVariableNames;
if (!self.arrayOfVariableNames)
{
self.arrayOfVariableNames = [[NSMutableArray alloc] init];
}
else
{
[self.arrayOfVariableNames removeAllObjects];
}
for (int i = 0; i< cols; i++)
{
NSString *tempString = [NSString stringWithCString:cArrayOfVariableNames[i] encoding:NSUTF8StringEncoding];
if([tempString length] > 0)
{
[self.arrayOfVariableNames addObject:tempString];
}
else
{
NSLog(#"string is empty");
}
}

How to parse JSON

How to parse this below "choices" on one array means when I have get "id" in array that all id values 108,109.... in 1st index in array but here is the 5 values in choices..so how to parse it
choices = (
{
id = 108;
label = Distributor;
},
{
id = 109;
label = "Clinical Lab";
},
{
id = 110;
label = Researcher;
},
{
id = 111;
label = "Current Customer";
},
{
id = 112;
label = "Past Customer";
}
);
Get in a single Step bro as
If your array is NSMutableArray then use as
NSArray *resultArray = [[NSArray arrayWithArray:temp] valueForKeyPath:#"id"]
If simple NSArray then use as
NSArray *resultArray = [jsonArray valueForKeyPath:#"id"]
You can do it using fast enumeration.
NSMutableArray *resultArray = [[NSMutableArray alloc] initWithCapacity:0];
// JSONDict is your JSON dict
for (NSDictionary *aDict in JSONDict[#"choices"]) {
[resultArray addObject:aDict[#"id"]];
}
NSLog(#"%#", resultArray);
Output:
(
108,
109,
110,
111,
112
)
If i understand your question properly, Then You can try this code for getting Ids in a Array:
NSMutableArray *arr = [[NSMutableArray alloc] init];
for (int i = 0;i<[choices count];i++)
{
[arr addObject:[[choices objectAtIndex:i] objectForKey:#"id"]];
}
NSLog(#"ID array : %#",arr);
[arr release];
try like this ,
NSMutableArray *idArray=[[NSMutableArray alloc]init];
for(int i=0;i<[jsonArray count];i++)
[idArray addObject:[[jsonArray objectAtIndex:i] valueForKey:#"id"]];
NSLog(#"%#",idArray);
here you'l get all the values in idArray.

Get matched string from two NSArrays

How can I save the string that match from one NSArray with one index difference in NSMutableArray?
For example, there are three "apple", four "pineapple", six "banana", two "cocoa" and the rest of words dont have duplicate(s) in the nsarray, i would like to know if the nsarray has at least two same words. If yes, I would like to save "apple", "pineapple, "banana" and "cocoa" once in nsmutablearray. If there are other alike words, I would like to add them to namutablearray too.
My code (which still doesn't work properly);
NSArray *noWords = [[NSArray alloc] initWithArray:
[[NSString stringWithContentsOfFile:[[NSBundle mainBundle]
pathForResource:#"words" ofType:#"txt"]
encoding:NSUTF8StringEncoding error:NULL]
componentsSeparatedByString:#"\n"]];
NSUInteger scount = [noWords count];
int ii = 0;
NSString *stringline;
for (ii; ii < scount; ii++)
{
stringline = [noWords objectAtIndex:ii];
NSLog(#"stringline : %# ", stringline);
}
int i = 1;
NSString *line;
for (i ; i < 10; i++)
{
line = [noWords objectAtIndex:i];
NSLog (#"line : %# ", line);
NSMutableArray *douwords = [NSMutableArray array];
if ([stringline isEqualToString:line])
{
NSString *newword;
for (newword in douwords)
{
[douwords addObject:newword];
NSLog (#"detected! %# ", douwords);
}
}
}
Here's a solution using two sets:
- (NSArray *)getDuplicates:(NSArray *)words
{
NSMutableSet *dups = [NSMutableSet set],
*seen = [NSMutableSet set];
for (NSString *word in words) {
if ([seen containsObject:word]) {
[dups addObject:word];
}
[seen addObject:word];
}
return [dups allObjects];
}
Assuming NSSet uses hash tables behind the scenes (which I'm betting it does), this is going to be faster than the previously suggested O(n^2) solution.
Here's something off the top of my head:
NSMutableSet* duplicates = [NSMutableSet set];
NSArray* words = [NSArray arrayWithObjects:#"Apple", #"Apple", #"Orange", #"Apple", #"Orange", #"Pear", nil];
[words enumerateObjectsUsingBlock:^(NSString* str, NSUInteger idx, BOOL *stop) {
for (int i = idx + 1; i < words.count; i++) {
if ([str isEqualToString:[words objectAtIndex:i]]) {
[duplicates addObject:str];
break;
}
}
}];
NSLog(#"Dups: %#", [duplicates allObjects]); // Prints "Apple" and "Orange"
The use of an NSSet, as opposed to an NSArray, ensures strings are not added more than once. Obviously, there are optimizations that could be done, but it should be a good starting point.
I assume that you want to count appearances of words in your array and output those with a count of more than one. A basic and verbose way to do that would be:
// Make an array of words - some duplicates
NSArray *wordList = [[NSArray alloc] initWithObjects:
#"Apple", #"Banana", #"Pencil",
#"Steve Jobs", #"Kandahar",
#"Apple", #"Banana", #"Apple",
#"Pear", #"Pear", nil];
// Make an mutable dictionary - the key will be a word from the list
// and the value will be a number representing the number of times the
// word appears in the original array. It starts off empty.
NSMutableDictionary *wordCount = [[NSMutableDictionary alloc] init];
// In turn, take each word in the word list...
for (NSString *s in wordList) {
int count = 1;
// If the word is already in the dictionary
if([wordCount objectForKey:s]) {
// Increse the count by one
count = [[wordCount objectForKey:s] intValue] + 1;
}
// Save the word count in the dictionary
[wordCount setObject:[NSNumber numberWithInt:count] forKey:s];
}
// For each word...
for (NSString *s in [wordCount keysOfEntriesPassingTest:
^(id key, id obj, BOOL *stop) {
if ([obj intValue] > 1) return YES; else return NO;
}]) {
// print the word and the final count
NSLog(#"%2d %#", [[wordCount objectForKey:s] intValue], s);
}
The output would be:
3 Apple
2 Pear
2 Banana

Compare two arrays and put equal objects into a new array [duplicate]

This question already has answers here:
Finding Intersection of NSMutableArrays
(5 answers)
Closed 8 years ago.
How can I compare two NSArrays and put equal objects into a new array?
NSArray *array1 = [[NSArray alloc] initWithObjects:#"a",#"b",#"c",nil];
NSArray *array2 = [[NSArray alloc] initWithObjects:#"a",#"d",#"c",nil];
NSMutableArray *ary_result = [[NSMutableArray alloc] init];
for(int i = 0;i<[array1 count];i++)
{
for(int j= 0;j<[array2 count];j++)
{
if([[array1 objectAtIndex:i] isEqualToString:[array2 objectAtIndex:j]])
{
[ary_result addObject:[array1 objectAtIndex:i]];
break;
}
}
}
NSLog(#"%#",ary_result);//it will print a,c
Answer:
NSArray *firstArr, *secondArr;
// init arrays here
NSMutableArray *intersection = [NSMutableArray array];
for (id firstEl in firstArr)
{
for (id secondEl in secondArr)
{
if (firstEl == secondEl) [intersection addObject:secondEl];
}
}
// intersection contains equal objects
Objects will be compared using method compare:. If you want to use another method, then just replace if (firstEl == secondEl) with yourComparator that will return YES to equal objects: if ([firstEl yourComparator:secondEl])
//i assume u have first and second array with objects
//NSMutableArray *first = [ [ NSMutableArray alloc]init];
//NSMutableArray *second = [ [ NSMutableArray alloc]init];
NSMutableArray *third = [ [ NSMutableArray alloc]init];
for (id obj in first) {
if ([second containsObject:obj] ) {
[third addObject:obj];
}
}
NSLog(#"third is : %# \n\n",third);
more over if u have strings in both array then look at this answer of mine
Finding Intersection of NSMutableArrays