Counting PList keys at a specific level - iphone

I'm trying to create a grouped tableview, but when it comes to the number rows in sections I haven't been able to get the correct values. From the list below 'OrdreLinje', 'OrdreStatus' and 'KundeLeveranse' are the sections and the items below would be the rows visible to the user. So the number of rows in the sections would be 4,1,1 respectively, my question is how do I count these keys to produce the correct result.
Root(Dict)
-->Rows(Array)
---->Item 0(Dict)
------>OrdreLinje(Array)
-------->item0(Dict)
-------->item1(Dict)
-------->item2(Dict)
-------->item3(Dict)
------>KundeLeveranse(Array)
-------->item0(Dict)
------>OrdreStatus(Array)
-------->item0(Dict)
Sorry, I did try to insert an image but i'm not reputable enough :)
Any help is greatly appreciated,
B

Are you wanting a count of the keys in the first dictionary in the Rows array, or the sum of the keys in all the dictionaries in the Rows array?
For the first, you could do:
NSArray *rows = [rootDict objectForKey:#"Rows"];
NSInteger count = 0;
if (rows.count > 0)
{
NSDictionary *firstRow = [rows objectAtIndex:0];
count = firstRow.allKeys.count;
}
If you want the count of all keys in all dictionaries in the Rows array, you could do:
NSArray *rows = [rootDict objectForKey:#"Rows"];
NSInteger count = 0;
for (NSDictionary *dict in rows)
{
count += dict.allKeys.count;
}

Related

Sorting of NSMutableDictionary

Confusing !!!
I have one NSMutableDictionary called tempDict, having keys Freight, Fuel , Discount (and many more) with relevant values.
I am generating two different NSMutableArrays called arrTVBuyCharge and arrTVBuyCost from tempDict using this Code :
[arrTVBuyCharge addObjectsFromArray:[(NSArray *)[tempDict allKeys]]];
[arrTVBuyCost addObjectsFromArray:[(NSArray *)[tempDict allValues]]];
Problem : I want Freight, Fuel and Discount at the Top in the above arrays in same order (Ofcourse , with Ordering of Values).
What is the Optimum way to achieve this ?
It seems tricky at first, but it's simple when you think about it. All you want to do is get a sorted list of keys, and look up the value for each key as you add them to your arrays.
To get an array with the list of sorted keys:
NSArray *sortedKeys = [[tempDict allKeys] sortedArrayUsingSelector:#selector(caseInsensitiveCompare:)];
Then iterate through those and add them to NSMutableArrays:
NSMutableArray *arrTVBuyCharge = [[NSMutableArray alloc] init];
NSMutableArray *arrTVBuyCost = [[NSMutableArray alloc] init];
for (NSString *key in sortedKeys) {
[arrTVBuyCharge addObject:key];
[arrTVBuyCost addObject:[tempDict objectForKey:key]];
}
For even better performance, use the initWithCapacity method for the NSMutableArrays since you know the size.
This is the standard way of doing it.
1) Get three objects separately :
NSArray *mainKeys = #[#"Freight", #"Fuel", #"Discount"];
NSArray *mainValues = #[[tempDict valueForKey:#"Freight"],
[tempDict valueForKey:#"Fuel"],
[tempDict valueForKey:#"Discount"]
];
[arrTVBuyCharge addObjectsFromArray:mainKeys];
[arrTVBuyCost addObjectsFromArray:mainValues];
2) Remove them from tempDict :
[tempDict removeObjectsForKeys:mainKeys];
3) Add the objects from Updated tempDict :
[arrTVBuyCharge addObjectsFromArray:(NSArray *)[tempDict allKeys]];
[arrTVBuyCost addObjectsFromArray:(NSArray *)[tempDict allValues]];
This will make Freight, Fuel and Discount to be at index 0, 1 and 2 in your new Arrays.
Man, NSMutableDictionary always returns keys in a disordered fashion, if you really want to maintain order then you can sort it in alphabetical order or you can add 01, 02 ,03 serial numbers before your values to sort them in the order they were put it, later trim the first two characters of the string and use it.

Sorting nsarray by index

I simply want to sort an NSArray by the index number i.e. The order in which the values are entered into the array.
My problem is that I use this array in a uipicker, and therefore when reusing labels, end up with my values in the wrong order
My values consist of fractions. 1/4,3/8,1/2,3/4,1,1-1/14,1-3/8 etc
I want these fractions to display in the order they are entered
Must be simple, but I am having no luck
When I use sorted array localisedstandardcompare all the values get out of sequence
Any help will be appreciated
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
// Only calls the following code if component "0" has changed.
if (component == 0)
{
// Sets the global integer "component0Row" to the currently selected row of component "0"
component0Row = row;
// Loads the new values for the selector into a new array in order to reload the data.
NSDictionary *newDict = [[NSDictionary alloc]initWithDictionary:[pickerData objectForKey:[selectorKeysLetters objectAtIndex:component0Row]]];
NSArray *sortArray = [[NSArray alloc]initWithArray:[newDict allKeys]];
NSMutableArray *newValues = [[NSMutableArray alloc]initWithArray:[sortArray sortedArrayUsingSelector:#selector(compare:)]];
self.selectorKeysNumbers = newValues;
component1Row = 0;
[self.myPicker selectRow:0 inComponent:1 animated:NO];
Your array is already sorted by the index number
Assuming that the array values are NSStrings the sort order will be by string value, not numeric value. In order to sort these fractions (rational numbers) you would have to write you own compare function.
But see #hypercrypt, the array should already be in the order entries were made.

Remove all objects after index 20 in NSMutableDictionary?

I have an NSMutableDictionary that possibly contains more than twenty objects.
If it contains more than 20 objects, how should I remove the oldest entries until there is only 20 left?
For example, NSMutableDictionary with objects:
a = "-1640531535";
b = 1013904226;
c = "-626627309";
d = 2027808452;
e = 387276917;
f = "-1253254618";
g = 1401181143;
h = "-239350392";
i = "-1879881927";
With max number of objects: 5, should become:
a = "-1640531535";
b = 1013904226;
c = "-626627309";
d = 2027808452;
e = 387276917;
Thank you.
If all you're looking for is 20 elements, I'd try something like:
NSMutableDictionary* newDict = [NSMutableDictionary new];
int count = 0;
for (id theKey in oldDict)
{
[newDict setObject:[oldDict getObjectForKey:theKey] forKey:theKey];
if (++count == 20)
break;
}
[oldDict release];
oldDict = newDict;
The idea being that you copy the elements of the first 20 keys you find into a new dictionary, then replace the old one with the new one. If you want to iterate the dictionary via other means you could do that too, but the code above wouldn't have to change much.
If the keys are NSNumbers and you know they're sequential, and you want to remove the lower values, then:
int limit=20; //set to whatever you want
int excess = limit - [dict count];
if (excess > 0) {
for (int i = 1; i <= excess; i++) {
[dict removeObjectForKey:[NSNumber numberWithInt:i]];
}
}
If your keys are NSStrings then just create the NSString with the corresponding format.
If your keys are not sequential, then you would have to either have a parallel dictionary with the date of storage for each entry, so you would know when each entry was stored and you can remove the oldest, or you need to use something else entirely (if you are storing sequential integers as keys, wouldn't it be easier to use NSMutableArray?)

ihow to acees random items from an array and then put them in another array in iphone sdk?

i have a problem i have an array which has ten items "one" to "ten"
i want to get randon items from this array and put them in a new array which can display the random items
// seed the random number generator
srand([[NSDate date] timeIntervalSince1970]);
// get random item
NSObject *randomItem = [yourArray objectAtIndex:rand() % [yourArray count]];
// insert item
[newMutableArray addObject:randomItem];

Objective C: Create arrays from first array based on value

I have an array of strings that are comma separated such as:
Steve Jobs,12,CA
Fake Name,21,CA
Test Name,22,CA
Bill Gates,44,WA
Bill Nye,21,OR
I have those values in an NSScanner object so that I can loop through the values and get each comma seperated value using objectAtIndex.
So, what I would like to do, is group the array items into new arrays, based on a value, in this case, State. So, from those, I need to loop through, checking which state they are in, and push those into a new array, one array per state.
CA Array:
Steve Jobs,12,CA
Fake Name,21,CA
Test Name,22,CA
WA Array:
Bill Gates,44,WA
OR Array:
Bill Nye,21,OR
So in the end, I would have 3 new arrays, one for each state. Also, if there were additional states used in the first array, those should have new arrays created also.
Any help would be appreciated!
You can use a NSMutableDictionary of NSMutableArrays - if the state encountered isn't yet in the dictionary, add a new array.
NSMutableArray* arr = [states objectForKey:state];
if (arr == nil) {
arr = [NSMutableArray array];
[states setObject:arr forKey:state];
}
Then you can insert values into the array, preferably as objects though as Dave DeLong mentions.
You shouldn't be maintaining this data as CSV. That's asking for a world of hurt if you ever need to manipulate this data programmatically (such as what you're trying to do).
You can naïvely break this data up into an array using NSArray * portions = [line componentsSeparatedByString:#","];. Then create a custom object to store each portion (for an example, see this post), and then you can manipulate those objects almost effortlessly.
Naively: (assuming array of strings called strings)
NSMutableDictionary *states = [NSMutableDictionary dictionary];
for (NSString *string in strings) {
NSString *state = [[string componentsSeparatedByString:#", "] lastObject];
NSMutableArray *values = [states objectForKey:state];
if (values == nil) {
values = [NSMutableArray array];
[states setObject:value forKey:state];
}
[values addObject:string];
}
Number of things about this -- first of all, I'm not at my computer, so there is a high chance of typos and or things that I missed. Second, you probably want to adapt the components separated by string line to handle whitespace better.