Multidimensional Arrays - iphone

im trying to populate a UITable with XML, i already have the xml parsed and stored in an array
ex.
array [item0, item1, item2, item3, item4, item5, item6, item7]
i need help trying to convert the array into an array that has 2 columns
ex
array [[item0, item1], [item2, item3], [item4, item5], [item6, item7]]
any help would be greatly appreciated
thanks

You could use something like this.
NSMutableArray *rootArray = [NSMutableArray array];
for (NSInteger i = 1; i < [items count]; i+=2) {
id object1 = [items objectAtIndex:i-1];
id object2 = [items objectAtIndex:i];
[rootArray addObject:[NSArray arrayWithObjects:object1, object2, nil]];
}
This will ignore the last object if you have a uneven number of objects in your array.
Edit, the version that doesn't ignore the last single object.
NSMutableArray *rootArray = [NSMutableArray array];
for (NSInteger i = 0; i < [items count]; i += 2) {
id object1 = [items objectAtIndex:i];
id object2 = nil;
if (i+1 < [items count]) {
object2 = [items objectAtIndex:i+1];
}
[rootArray addObject:[NSArray arrayWithObjects:object1, object2, nil]];
}

make structure some thing like this
NSMutableArray *dictArray=[NSMutableArray alloc] init];
for(int i=0;i<[array count];i=i+2)
{
NSMutableDictionary *dict=[[NSMutableDictionary alloc] init];
[dict setObject:[array objectAtIndex:i] forKey:#"first"];
if([array count]>(i+1))
[dict setObject:[array objectAtIndex:(i+1)] forKey:#"second"];
[dictArray addObject:dict];
[dict release];
}
[dictArray release];

Related

How to compare two MutableArrays and display the unmatched value in iphone? [duplicate]

This question already has answers here:
Compare 2 nsmutablearray and get different object to third array in ios
(4 answers)
Closed 9 years ago.
I have two MutableArray values like.
NSMutableArray *array=[[NSMutableArray alloc]initWithObjects:#"Apple", #"Orange", #"Grapes", #"Banana", nil];
NSMutableArray *array1=[[NSMutableArray alloc]initWithObjects:#"Apple", #"Orange", #"Grapes", nil];
Now i have to compare that two Mutable arrays and display that unmatched object "Banana" into one string.
I am fresher to iOS so, anybody would send me the code for that problem.
Thanks in Advance.
As others have suggest, NSSet is probably your best bet. However, given that *array is mutable, you could simply remove the objects from it contained in *array1
NSMutableArray *array=[[NSMutableArray alloc]initWithObjects:#"Apple", #"Orange", #"Grapes", #"Banana", nil];
NSMutableArray *array1=[[NSMutableArray alloc]initWithObjects:#"Apple", #"Orange", #"Grapes", nil];
[array removeObjectsInArray:array1];
NSLog(#"array: %#", array); // array: ( Banana )
// if you require result as a string
NSString *objectsAsString = [array componentsJoinedByString:#", "];
NSLog(#"objects as string: %#", objectsAsString); // objects as string: Banana
for(int i=0;i<[array count];i++)
{
NSString *str1 = [array objectAtIndex:i];
for(int j=0;j<[array1 count];j++)
{
NSString *str2 = [array1 objectAtIndex:j];
if([str1 isEqualToString:str2])
{
//do something which you want i.e add the values to some other array
}
}
}
You should probably use NSSet for this purpose
NSSet *set1 = [NSSet setWithObjects:#"a", #"s", #"d", #"f", nil];
NSSet *set2 = [NSSet setWithObjects:#"a", #"s", nil];
NSMutableSet *notInSet1 = [NSMutableSet setWithSet:set2];
[notInSet1 minusSet:set1];
NSMutableSet *notInSet2 = [NSMutableSet setWithSet:set1];
[notInSet2 minusSet:set2];
NSMutableSet *symmetricDifference = [NSMutableSet setWithSet:notInSet1];
[symmetricDifference unionSet:notInSet2];
NSArray *array1 = [[NSArray alloc] initWithObjects:#"a",#"b",#"c",nil];
NSArray *array2 = [[NSArray alloc] initWithObjects:#"a",#"d",#"c",nil];
NSMutableArray *ary_result = [[NSMutableArray alloc] init];
NSMutableArray *ary_resultUnmatched = [[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]];
} else {
[ary_resultUnmatched addObject:[array1 objectAtIndex:i]];
}
}
}
NSLog(#"%#",ary_result);//it will print a,c
NSLog(#"%#",ary_resultUnmatched);//it will print b,d
so in else condition you'll have your un matched values

Initialize multiple objects with different name

How can I Initialize and allocate multiple objects with different name and pass it to the NSArray. from Below code the object is initialized once in loop and I need to initialized multiple times as per the For loop will go with different name..and then pass it to NSArray.please check the code below..
when For loop will start means i=0 ..initialized item would betempItemi
now next time when i=1 and i=2 the tempItemi name will be same .how can i change this with in loop..and pass it to NSArray *items
for (int i = 0; i< [Array count]; i++)
{
id object = [Array objectAtIndex:i];
if ([object isKindOfClass:[NSDictionary class]])
{
NSDictionary *objDict = (NSDictionary *)object;
ECGraphItem *tempItemi = [[ECGraphItem alloc]init];
NSString *str = [objDict objectForKey:#"title"];
NSLog(#"str value%#",str);
float f=[str floatValue];
tempItemi.isPercentage=YES;
tempItemi.yValue=f;
tempItemi.width=30;
NSArray *items = [[NSArray alloc] initWithObjects:tempItemi,nil];
//in array need to pass all the initialized values
[graph drawHistogramWithItems:items lineWidth:2 color:[UIColor blackColor]];
}
}
Why dont you just make the array mutable and then add the object each time like this:
NSMutableArray *items = [[NSMutableArray alloc] init];
// a mutable array means you can add objects to it!
for (int i = 0; i< [Array count]; i++)
{
id object = [Array objectAtIndex:i];
if ([object isKindOfClass:[NSDictionary class]])
{
NSDictionary *objDict = (NSDictionary *)object;
ECGraphItem *tempItemi = [[ECGraphItem alloc]init];
NSString *str = [objDict objectForKey:#"title"];
NSLog(#"str value%#",str);
float f=[str floatValue];
tempItemi.isPercentage=YES;
tempItemi.yValue=f;
tempItemi.width=30;
[items addObject: tempItemi];
//in array need to pass all the initialized values
}
}
[graph drawHistogramWithItems:items lineWidth:2 color:[UIColor blackColor]];
Anyways items in your original code will be reinitializing each time and you are drawing a new histogram each time so your code won't work... This should work...
The code you have written is ok but,
NSArray *items will always contain only one item at each loop.
just declare that outside for loop as NSMutableArray,
and go with the same code you are using.
As you said you want to make variable dynamically as
ECGraphItem *tempItemi = [[ECGraphItem alloc]init];
here i will be changing in the loop,
You can create a NSDictionary with key/value as per with your tempItem1/2/3/4.... as key and save values by alloc/init.
Then instead of a variable tempItem32, you will be using [dict valueForKey:#"tempItem32"].
EDIT:
Check this example if this may come handy
NSMutableDictionary *dict=[NSMutableDictionary new];
for (int i=1; i<11; i++) {
NSString *string=[NSString stringWithFormat:#"string%d",i];
[dict setObject:[NSString stringWithFormat:#"%d", i*i] forKey:string];
}
NSLog(#"dict is %#",dict);
NSString *fetch=#"string5";
NSLog(#"val:%#, for:%#",[dict valueForKey:fetch],fetch);

Sum duplicate on NSMutableArray

I have a NSMutableArray with objects of type NSMutableDictionary,
the NSMutableDictionary contains 2 keys
-Airlines (string)
-Rating (integer)
I have an NSMutableArray with all the objects and what i need is to Sum the rating of all the airline companies repeated objects, an example:
Airline Rating
A 2
B 3
B 4
C 5
The end result array will be the A = 2, C = 5 and the Sum of B´s that is equal to 7.
My code so far:
for (int i = 0; i < arrayMealRating.count; ++i) {
NSMutableDictionary *item = [arrayMealRating objectAtIndex:i];
NSLog(#"item=%#",item);
for (int j = i+1; j < arrayMealRating.count; ++j)
{
if ([[item valueForKey:#"Airline"] isEqualToString:[arrayMealRating objectAtIndex:j]]){
NSMutableDictionary *item = [arrayMealRating objectAtIndex:j];
NSMutableDictionary *item1 = [arrayMealRating objectAtIndex:i];
NSInteger auxCount = [[item valueForKey:#"setMealRating"] integerValue] + [[item1 valueForKey:#"setMealRating"] integerValue];
NSMutableDictionary *aux = [NSMutableDictionary dictionaryWithObjectsAndKeys:[item valueForKey:#"Airline"], #"Airline"
,[NSString stringWithFormat:#"%d",auxCount], #"setMealRating"
,nil];
NSLog(#"aux=%#",aux);
[arrayMealRating replaceObjectAtIndex:i withObject:aux];
}
}
}
A bit messy i know but i dont know how to work with NSMutableDictionary, any help will be much appreciated, Thanks in Advance!
Incase you dont want to change how your storing the data, heres how you would do it using key-value coding. Heres the dirrect link to the documentation for #distinctUnionOfObjects and #sum.
// Get all the airline names with no duplicates using the KVC #distinctUnionOfObjects collection operator
NSArray *airlineNames = [arrayMealRating valueForKeyPath:#"#distinctUnionOfObjects.Airline"];
// Loop through all the airlines
for (NSString *airline in airlineNames) {
// Get an array of all the dictionaries for the current airline
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"(Airline == %#)", airline];
NSArray *airlineMealRating = [arrayMealRating filteredArrayUsingPredicate:predicate];
// Get the sum of all the ratings using KVC #sum collection operator
NSNumber *rating = [airlineMealRating valueForKeyPath:#"#sum.Rating"];
NSLog(#"%#: %#", airline, rating);
}
This gives the following output
A: 2
B: 7
C: 5
I would suggest to redesign that entirely if that's at all possible.
Create a class Airline
#interface Airline : NSObject
#property (strong, nonatomic) NSString *name;
#property (strong, nonatomic) NSMutableArray *mealRatings;
- (void)addMealRating:(float)rating;
- (float)sumOfMealRatings;
#end
#implementation
- (id)initWithName:(NSString *)pName
{
self = [super init];
if (self)
{
self.name = pName;
self.mealRatings = [NSMutableArray array];
}
return self;
}
- (void)addMealRating:(float)rating
{
[self.mealRatings addObject:#(rating)];
}
- (float)sumOfRatings
{
float sum = 0;
for (NSNumber *rating in self.mealRatings)
{
sum += [rating floatValue];
}
}
#end
Then in your 'mainclass' you simply hold an NSArray with instances of your Airline objects. It might require you to change some of your existing code, but I think in the long run it saves you time and trouble. Perhaps you recognize later on, that you want to add additional properties to your Airlines. A dictionary is a cumbersome way to do that.
#try this
NSMutableArray *myArray = [[NSMutableArray alloc] initWithCapacity:4];
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
[dict setValue:[NSNumber numberWithInteger:2] forKey:#"A"];
[myArray addObject:dict];
NSMutableDictionary *dict2 = [[NSMutableDictionary alloc] init];
[dict2 setValue:[NSNumber numberWithInteger:3] forKey:#"B"];
[myArray addObject:dict2];
NSMutableDictionary *dict3 = [[NSMutableDictionary alloc] init];
[dict3 setValue:[NSNumber numberWithInteger:4] forKey:#"B"];
[myArray addObject:dict3];
NSMutableDictionary *dict4 = [[NSMutableDictionary alloc] init];
[dict4 setValue:[NSNumber numberWithInteger:5] forKey:#"D"];
[myArray addObject:dict4];
NSMutableDictionary *resultDictionary = [[NSMutableDictionary alloc] init];
for(NSMutableDictionary *dictionary in myArray)
{
NSString *key = [[dictionary allKeys] objectAtIndex:0];
NSInteger previousValue = [[resultDictionary objectForKey:key] integerValue];
NSInteger value = [[dictionary objectForKey:key] integerValue];
previousValue += value;
[resultDictionary setObject:[NSNumber numberWithInteger:previousValue] forKey:key];
}
for(NSString *key in resultDictionary)
{
NSLog(#"value for key = %# = %d",key, [[resultDictionary valueForKey:key] integerValue]);
}

copying three different array to one array

I have three array..say array1,array2,array3. All these arrays contains dictionary.Now, I want to copy all the objects of these array into a single array and display in table view.
My problem is that how will I copy those three array into 1.
Say;
NSMutableArray *array1 = [NSMutableArray arrayWithObject:Dict1];
NSMutableArray *array2 = [NSMutableArray arrayWithObject:Dict2];
NSMutableArray *array3 = [NSMutableArray arrayWithObject:Dict3];
Now, I want to copy the contains of array1, array2, array3 into array4.How will I do this.
Use this
NSMutableArray *array4 = [[NSMutableArray alloc] init];
[array4 addObjectsFromArray:array1];
[array4 addObjectsFromArray:array2];
[array4 addObjectsFromArray:array3];
//Do something on array4
[array4 release];
NSMutableArray *allObjs = [[NSMutableArray alloc] initWithArray: array1];
[allObjs addObjectsFromArray: array2];
[allObjs addObjectsFromArray: array3];
NSMutableArray *array4 = [[NSMutableArray alloc] init];
for (int i = 0; i < [array1 count]; i++)
{
[array4 addObject:[array1 objectAtIndex:i]];
}
for (int i = 0; i < [array2 count]; i++)
{
[array4 addObject:[array2 objectAtIndex:i]];
}
for (int i = 0; i < [array3 count]; i++)
{
[array4 addObject:[array3 objectAtIndex:i]];
}
//use your array4
[array4 release];
NSMutableArray * array4 = [NSMutableArray arrayWithObjects:[array1 objectAtIndex:0], [array2 objectAtIndex:0], [array3 objectAtIndex:0]];

how to remove duplicate value in NSMutableArray

i'm scanning wifi info using NSMutableArray, but there are few duplicate values appear, so i try to use following code but still getting the duplicate values,
if([scan_networks count] > 0)
{
NSArray *uniqueNetwork = [[NSMutableArray alloc] initWithArray:[[NSSet setWithArray:scan_networks] allObjects]];
[scan_networks removeAllObjects];
NSSortDescriptor *networkName = [[[NSSortDescriptor alloc] initWithKey:#"SSID_STR" ascending:YES] autorelease];
NSArray *descriptors = [NSArray arrayWithObjects:networkName,nil];
[scan_networks addObjectsFromArray:[uniqueNetwork sortedArrayUsingDescriptors:descriptors]];
}
how this can be resolve, thanks
You can use NSSET but if you it is only used when order doesn't matter if order matter then go for this approach.I have used it and it give perfect answer. in Place of NSmutableArray array put your NSmutableArray which contains duplicate Value.
NSArray *copy = [NSmutableArray copy];
NSInteger index = [copy count] - 1;
for (id object in [copy reverseObjectEnumerator])
{
if ([NSmutableArray indexOfObject:object inRange:NSMakeRange(0, index)] != NSNotFound)
{
[NSmutableArray removeObjectAtIndex:index];
}
index--;
}
[copy release];
You should be using an NSMutableSet in the first place.
For eliminating all double entries in an array, see this question:
Make NSMutableArray or NSMutableSet unique.
Here is the code of removing duplicates values from NSMutable Array..it will work for you.
myArray is your Mutable Array that you want to remove duplicates values..
for(int j = 0; j < [myArray count]; j++){
for( k = j+1;k < [myArray count];k++){
NSString *str1 = [myArray objectAtIndex:j];
NSString *str2 = [myArray objectAtIndex:k];
if([str1 isEqualToString:str2])
[myArray removeObjectAtIndex:k];
}
}
// Now print your array and
I think its better to do this:
NSMutableIndexSet *indexes = [[NSMutableIndexSet alloc]init];
for(int j = 0; j < [myArray count]; j++) {
for( k = j+1;k < [myArray count];k++) {
NSString *str1 = [myArray objectAtIndex:j];
NSString *str2 = [myArray objectAtIndex:k];
if([str1 isEqualToString:str2])
[indexes addIndex:k];
}
}
[myArray removeObjectsAtIndexes:indexes];
You can run into problems if you manipulate the array while looping in my experience.
This is another way:
- (NSArray *)removeDuplicatesFrom:(NSArray *)array {
NSSet *set = [NSSet setWithArray:array];
return [set allObjects];
}
maybe you can try the NSArray category.
#import <Foundation/Foundation.h>
#interface NSArray(filterRepeat)
-(NSArray *)filterRepeat;
#end
#import "NSArray+repeat.h"
#implementation NSArray(filterRepeat)
-(NSArray *)filterRepeat
{
NSMutableArray * resultArray =[NSMutableArray array];
[self enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
if (![resultArray containsObject: obj]) {
[resultArray addObject: obj];
}
}];
return resultArray;
}
#end