Count number of JSON objects - Objective-C - objective-c

Example JSON:
{ "image" : "http:\/\/www.domain.com\/blah\/blah\/blah\/5yph0gbfj3ip41a.jpg",
"0" : { "thing1" : "Hello",
"thing2" : "06\/21\/2013"
},
"1" : { "thing1" : "Goodbye",
"thing2" : "06\/28\/2013"
}
}
How can I count the number of times the "0" : {whatever} appears? They'd be increasing by one. Like for the above example, I want it to return 2.
I'm reading JSON from an id : [zoneJSONobject objectForKey:#"thing1"];

One approach would be to use the - [NSDictionary count] method (see docs) for the total number of keys, and then subtract what you don't want to count if it's present (like "image" for example.)
Another approach would be to iterate through the keys like:
int keyCount = 0;
for (NSString *key in myDict)
if (/* the string is a number */ )
keyCount++;
(There are plenty of separate SO articles on testing if a string is a number.)
However, the best approach would be to modify the JSON object to return these dictionaries to you inside an array, that way you don't have to count them before you start iterating. I'm not sure if that option is available to you.

It seems that there's one leading entry for the image, then all the items you want to count. Then you can use the subtraction operator:
int n = dictionary.count - 1;

you want to count the root keys? Use the buit-in NSJSONserialization class to create NSObjects from it. In this case you will get an NSDictionary. Call its allKeys property and then that's count property!

Related

Writing a method in Java about ArrayList (getting the first match among similar length)

I am new to java and I am writing a method that returns the longest song from a playlist(ArrayList) using only the minutes. if multiple songs have the same longest length, it will return the first encountered song. How to ensure it returns the first longest song and not the last longest song.
public Song getLongestSong() {
if (this.songs.isEmpty()) {
return null;
}
Song longestSong = this.songs.get(0);
for (Song songs: this.songs) {
if (songs.getMinutes() >= longestSong.getMinutes()) {
longestSong = songs; `
}
}
return longestSong;
}
This looks like a homework assignment, so I'm not going to give an exact answer https://cs.millersville.edu/~autolab/161-f21/mutunesobject/.
Think about the check in the if (songs.getMinutes() >= longestSong.getMinutes() statement. If there is already a value set for longestSong and another song comes in with the same length, what will happen? How do you avoid that?

Selection a bool through randomizer

I have a total of 6 booleans and the only thing separating them is a number. They're named checker0 though 5.
So checker0, checker1, checker2, checker3, checker4 and checker5.
All of these grants or denies access to certain parts of the app wether the bool is true or false.
I then have a randomiser using:
randomQuestionNumber = arc4random_uniform(5);
So say we get number 3, checker3 = true;
But my question now is would it be possible to set this one to true without having to go thru if statements.
My idea was to implement the way you print a int to say the NSLog using the %d.
NSLog(#"The number is: %d", randomQuestionNumber);
So something like:
checker%d, randomQuestionNumber = true.
Would something like that be possible? So i won't have to do like this:
if (randomQuestionNumber == 0) {
checker0 = true;
}
else if (randomQuestionNumber == 1)
{
checker1 = true;
}
Thanks you very much! :)
Every time you find yourself in a situation when you name three or more variables checkerN you know with a high degree of probability that you've missed a place in code where you should have declared an array. This becomes especially apparent when you need to choose one of N based on an integer index.
The best solution would be to change the declaration to checker[6], and using an index instead of changing the name. If this is not possible for some reason, you could still make an array of pointers, and use it to make modifications to your values, like this:
BOOL *ptrChecker[] = {&checker0, &checker1, &checker2, ...};
...
*ptrChecker[randomQuestionNumber] = true;

For with multiple in

I want to use the basic Objective C stament for (id object in collection) with multiple objects and conditions like this:
for (Origin *origin in [self.fetchedOriginController fetchedObjects] AND Destiny *destiny in [self.fetchedDestinyController fetchedObjects]))
{
NSLog(#"This route starts from %# and ends in %#, origin.name, destiny.name);
}
So the log would be:
This route starts in London and ends in Sidney
This route starts in Madrid and ends in Barcelona
This route starts in Washington and ends in Vienna
(...)
How can this be done?
If you are looking for all combinations just nest:
for (object in collection)
{
for (object2 in collection2)
{
...
}
}
Or are you looking for pairs of objects from two same sized collections? If so create a loop which provides the index:
NSUInteger count = collection.count;
for (NSUInteger ix = 0; ix < count; ix++)
{
id object = collection[ix];
id object2 = collection2[ix];
...
}
If you want to loop over the common pairs of two different sized collections just change the first line to:
NSUInteger count = MIN(collection.count, collection2.count);
If you want something else edit your question to be more explicit.
Something like this would work for what you're trying I think:
for (NSUInteger i = 0; i < collection1.count; i++) {
id object1 = collection1[i];
id object2 = collection2[i];
// continue ...
}
As far as I know, there's no built in syntax to do what you're asking.
This solution makes the assumption that collection1 and collection2 have the same amount of objects, or at least collection2 doesn't exceed collection1 in count. Given your desired syntax, I think you have already planned for this, I just wanted to mention it in case someone else stumbles on this.
What order do you expect this enumeration to happen in? What kind of association between objects from each collection are you looking for?
If you want to take each object from collection and do something with both that object and each object2 in collection2, use nested loops:
for (object in collection) {
for (object2 in collection2) {
// ...
}
}
If you want to go through both collections in order, use two loops.
for (object in collection) { /* ... */ }
for (object2 in collection2) { /* ... */ }
If you expect some sort of mapping between the objects in collection and collection2 (which presumes they have the same count and at least one of them has unique entries), you might look into a data structure that captures that mapping. Then you can iterate across pairs.
NSDictionary *dictionary = [NSDictionary dictionaryWithObjects:collection2 forKeys:collection];
[dictionary enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop){
// ...
}];

Objective-C: Adding to variable before assignment

I have the following code:
NSInteger variableScene = 10;
NSInteger numberOfRowsXX = //an Integer value; <-- I would like replace XX with the value of 'variableScene'
So it'll look like this:
NSInteger numberOfRows10 == //an Integer value;
How can I replace XX with the value of variableScene?
*Update*
Why I'm trying accomplish this?
It's a bit complicated. I'm using Core Data with remote Database. In a nutshell: I have 10 Scenes that'll be presented based on the User selection order. For each Scene I need to assign the numberOfRows to present at the end of all the Scenes with a UITableViewController.
I have a variableScene that I pass around from Scene to Scene.
I need to assign numberOfRowsSceneXX = //an integer
XX will come from variableScene, which could be any number from 1 - 10.
So when we get to the last scene, we'll have a value for each Section (numberOfRowInSection) which will be represented by each Scene: numberOfRowScene1, numberOfRowsScene2, etc.
I tried to simplify the question. Hope it makes sense.
Use arrays.
set it up as:
#define MAX_SCENES 10
NSInteger numberOfRows[MAX_SCENES];
then when you want to set the value:
if (variableScene < MAX_SCENES) {
numberOfRows[variableScene] = variable;
}

How to return a C-array from method in Objective-C?

I have a function that returns a variable and I want to know how to return an array the issue is it isn't an NSArray it is just an average C array like this...
-(b2Fixture*) addFixturesToBody:(b2Body*)body forShapeName:(NSString*)shape
{
BodyDef *so = [shapeObjects objectForKey:shape];
assert(so);
FixtureDef *fix = so->fixtures;
int count = -1;
b2Fixture *Fixi[4];
while(fix)
{
count++;
NSLog(#"count = %d",count);
Fixi[count]= body->CreateFixture(&fix->fixture);
if (Fixi[count]!=0) {
NSLog(#"Fixi %d is not 0",count);
}
if (body->CreateFixture(&fix->fixture)!=0) {
NSLog(#"body %d is not 0",count);
}
fix = fix->next;
}
return *Fixi;
}
If you see some variable types you don't know it's because I'm using cocos2d framework to make a game but I'm returning a variable of b2Fixture... This code compiles however only saves the value of the first block of the array "fixi[0]" not the whole array like I want to pass
anyhelp :) thankyou
You can't return a local array. You'll need to do some kind of dynamic allocation or pull a trick like having the array inside a structure.
Here is a link to an in-depth article that should help you out.
In general returning C arrays by value is a bad idea, as arrays can be very large. Objective-C arrays are by-reference types - they are dynamically allocated and a reference, which is small, is what is passed around. You can dynamically allocate C arrays as well, using one of the malloc family for allocation and free for deallocation.
You can pass C structures around by value, and this is common, as in general structures tend to be small (or smallish anyway).
Now in your case you are using a small array, it has just 4 elements. If you consider passing these 4 values around by value is reasonable and a good fit for your design then you can do so simply by embedding the C array in a C structure:
typedef struct
{
b2Fixture *elements[4];
} b2FixtureArray;
...
-(b2FixtureArray) addFixturesToBody:(b2Body*)body forShapeName:(NSString*)shape
{
BodyDef *so = [shapeObjects objectForKey:shape];
assert(so);
FixtureDef *fix = so->fixtures;
int count = -1;
b2FixtureArray Fixi;
while(fix)
{
count++;
NSLog(#"count = %d", count);
Fixi.elements[count]= body->CreateFixture(&fix->fixture);
if (Fixi.elements[count] != 0)
{
NSLog(#"Fixi %d is not 0",count);
}
if (body->CreateFixture(&fix->fixture) != 0)
{
NSLog(#"body %d is not 0", count);
}
fix = fix->next;
}
return Fixi;
}
...
// sample call outline
b2FixtureArray result = [self addFixturesToBody...]
Whether this standard C "trick" for passing arrays by value is appropriate for your case you'll have to decide.
Note: If b2fixture is an Objective-C object make sure you understand the memory management implications of having a C array of objects references depending on the memory management model (MRC, ARC, GC) you are using.
If you need to design function or method that has to return a fixed or limited size array, one possibility is to pass a pointer to the result array to the function or method as a parameter. Then the caller can take care of allocating space, or just use a local or instance variable array. You might want the called function to sanity check that the array parameter isn't NULL before using the array.