I have to 2 NSMutableArrays containing NSMutableDictionarys. I need to verify the dictionaries in one of the arrays exists in the other array. How can I do this?
I'm not sure if this is the best approach but it is an easy one. I created a method to verify if a NSDictionary is present inside a NSArray. Inside this function, I convert the NSDictionarys to NSStrings and compare them.
- (BOOL)verifyIfDictionary:(NSDictionary *)dict existsInsideArray:(NSArray *)array
{
BOOL result = NO;
NSString *dictStr = [NSString stringWithFormat:#"%#",dict]; // convert dictionary to string
for (NSDictionary *d in arrayOfDictionaries)
{
NSString *dStr = [NSString stringWithFormat:#"%#",dict]; // same conversion as above conversion
// now, I just have to compare the resulting strings
if ([dictStr isEqualToString:dStr])
result = YES;
}
return result;
}
Now you just have to iterate through one of your NSArrays and use this method, like this:
NSArray *arrayOfDictionaries1;
NSArray *arrayOfDictionaries2;
// initialize them, fill with data, do your processing.. etc, etc...
// then, when you want to verify:
for (NSDictionary *dict in arrayOfDictionaries1)
{
if ([self verifyIfDictionary:dict existsInsideArray:arrayOfDictionaries2])
{
NSLog(#"exists!");
}
}
To check if array1 contains all of the items in array2:
NSMutableArray *mutableArrayToCheck = [array2 mutableCopy];
[mutableArrayToCheck removeObjectsInArray:array1];
if (array2.count > 0 && mutableArrayToCheck.count == 0) {
// array2 contains all the items in array1
}
Ignore the type of the contents of the arrays for a second, just think of numbers. We have 2 arrays:
array1 = [ 1, 2, 3 ]
array2 = [ 1, 3 ]
If we remove the items in array1 from array2, and the result is an empty array, then we know that all of the items in array2 were also in array1.
removeObjectsInArray: does this for us by searching through the array and comparing each item. We just need to check the result.
This works no matter what the contents of the array are, so long as they implement hash and isEqual:.
Related
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Generating permutations of NSArray elements
Let's say that I have
[1,2]
And I want to get
{1}
{2}
{1, 2}
{2, 3}
I think the name of the thing you're looking for is 'power set'. It sounded fun, so here's a crack at it. I relied on this very concise article for the algorithm. I'm not sure if this is efficient (...actually, I'm sure this is inefficient) over large sets.
// answer the powerset of array: an array of all possible subarrays of the passed array
- (NSArray *)powerSet:(NSArray *)array {
NSInteger length = array.count;
if (length == 0) return [NSArray arrayWithObject:[NSArray array]];
// get an object from the array and the array without that object
id lastObject = [array lastObject];
NSArray *arrayLessOne = [array subarrayWithRange:NSMakeRange(0,length-1)];
// compute the powerset of the array without that object
// recursion makes me happy
NSArray *powerSetLessOne = [self powerSet:arrayLessOne];
// powerset is the union of the powerSetLessOne and powerSetLessOne where
// each element is unioned with the removed element
NSMutableArray *powerset = [NSMutableArray arrayWithArray:powerSetLessOne];
// add the removed object to every element of the recursive power set
for (NSArray *lessOneElement in powerSetLessOne) {
[powerset addObject:[lessOneElement arrayByAddingObject:lastObject]];
}
return [NSArray arrayWithArray:powerset];
}
If you think this is a keeper, you could make it a category method on array and drop the parameter. Test it like this...
NSLog(#"empty = %#", [self powerSet:[NSArray array]]);
NSLog(#"one item = %#", [self powerSet:[NSArray arrayWithObject:#"a"]]);
NSLog(#"two items = %#", [self powerSet:[NSArray arrayWithObjects:#"a", #"b", nil]]);
NSLog(#"three items = %#", [self powerSet:[NSArray arrayWithObjects:#"a", #"b", #"c", nil]]);
I did only these tests, and the output looked good. Spoiler alert: the three item test looks roughly like this on my console (with \n's removed):
three items = ((),
(a),
(b),
(a,b),
(c),
(a,c),
(b,c),
(a,b,c))
I am getting below response into the nsarray when I used the JSON parsing from my required URL but here I don't like to get 2,1,4,4,6,5,8,7,10,9,12 and 11 in single array I have to get total response into two arrays I mean one array set will consists 2,4,6,8,10 and other array set must be 3,5,7,9 and 11.
So how is the code for separation of single array response into two arrays in iPhone?
"(\n 2,\n 1\n)",
"(\n 4,\n 3\n)",
"(\n 6,\n 5\n)",
"(\n 8,\n 7\n)",
"(\n 10,\n 9\n)",
"(\n 12,\n 11\n)"
If you combine every number into one large array, you could feasibly test if each number is even or odd with a simple if-else in a for-in loop. Maybe like this:
-(NSArray*)parseJSONIntoArrays:(NSArray*)array {
NSMutableArray *evenNumbers = [[NSMutableArray alloc]init];
NSMutableArray *oddNumbers = [[NSMutableArray alloc]init];
for (NSNumber *number in array) {
if (([number intValue] %2) == 0) {
//even
[evenNumbers addObject:number];
}
else {
//odd
[oddNumbers addObject:number];
}
}
return [[NSArray alloc]initWithObjects:evenNumbers, oddNumbers, nil];
}
To split an array, you usually need to loop through all of the values and use an IF ELSE structure to decide which array to put the values in. Also, you need to use NSMutableArray instead of NSArray. Something like this:
NSMutableArray *evenNumbers = [NSMutableArray new];
NSMutableArray *oddNumbers = [NSMutableArray new];
for (NSNumber *value in myArray) {
if ([value intValue] % 2 == 0) {
[evenNumbers addObject:value];
} else {
[oddNumbers addObject:value];
}
}
I'm developing for iOS 5, say I have 2 arrays, the second only contains items contained on the first one.
I want to remove this object in every array it's present.
So, is there a way to easily remove an object from all arrays that contains it?
NSMutableArray *totalArray = [ [ NSMutableArray alloc] init];
//here i assume u want to delete NSString object vijay in all arrays
NSString *toDelete=#"vijay";
[totalArray addObject:firstArray];
[totalArray addObject:secondArray];
for (NSMutableArray *arr in totalArray) {
if ([arr containsObject:toDelete]) {
[arr removeObject:toDelete];
}
}
NSLog(#"firstarry : %# \n\n",firstArray);
NSLog(#"secondarray : %# \n\n",secondArray);
I am trying to detect if an array isn't empty in order to be able to do a certain call.
I tried using if (![array ==nil]) however that doesn't compile.
I'm sure there is a really easy explanation to this.
Update
If array is empty I want to do this:
array = [[NSMutableArray alloc]init];
If it has an object I want to do this:
array = [[userDefaults arrayForKey:#"MyFavorites"] mutableCopy];
If you declared it but did not assign anything to it at all:
NSMutableArray *array;
Then the array will be nil, meaning it isn't there at all so you can't say if it's empty or not, so you can't check anything.
If you did assign something to it, and you want to find out if the existing array is empty or not, that would depend on how you created it first.
If the array was assigned from some convenience method, it's autoreleased, so just do this:
if ([array count] == 0) {
array = [[NSMutableArray alloc] init];
} else {
array = [[userDefaults arrayForKey:#"MyFavorites"] mutableCopy];
}
If the array was assigned from an init or copy method, or it was retained previously, store the count in a temporary variable, release the array and use the temporary variable to decide what to do:
NSInteger count = [array count];
[array release];
if (count == 0) {
array = [[NSMutableArray alloc] init];
} else {
array = [[userDefaults arrayForKey:#"MyFavorites"] mutableCopy];
}
In your case I'd always use without differentation
array = [[userDefaults arrayForKey:#"MyFavorites"] mutableCopy];
and set the default value in the user defaults to an empty array right away at program start before accessing the defaults (from Apple's example):
+ (void)initialize{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSDictionary *appDefaults = [NSDictionary
dictionaryWithObject:[NSArray array] forKey:#"MyFavorites"];
[defaults registerDefaults:appDefaults];
}
See Apple's doc on this.
Supposing you are talking about NSArray, if myArray has not been properly alloced+initialized (what you are trying to check) its reference will be nil, so you can do:
if(myArray) //or even if(myArray != nil) since myArray will be a pointer
{
//properly inizialized
}
else
{
//not properly inited
}
If it's been inited on the other hand, you can test its emptiness by checking the count property which returns the number of elements it contains
if([myArray > 0])
//there is at least one element
}
else
{
//no elements
}
you can use count function of NSArray. it will work on NSMutableArray too....
syntext will be,
int ct=[array count];
ct will have number of items in array.
if it us empty it will be Zero
is this the right way to do the same?
nsmutablearray *myarray1 //have some data in it
for (int i=0;i< [myarray1 count]; i++)
{
myArray2 = [NSMutableArray array];
[myArray2 addObject:i];
}
and how can i print this value of myarray2.
If you are trying to copy element of one array to other array then use following code:
NSMutableArray *secondArray = [NSMutableArray arrayWithArray:firstArray];
If you want to print element value then depending upon data stored in your array you can print element.
i.e if array contains string object then you can print like this:
for(int i=0;i<secondArray.count;i++)
{
NSLog(#"Element Value : %#",[secondArray objectAtIndex:i]);
}
if array contains any user define object then you can print like this:
for(int i=0;i<secondArray.count;i++)
{
UserDefineObject *obj = [secondArray objectAtIndex:i];
NSLog(#"Element Value with property value: %#",obj.property);
}
The easiest way to create a new array containing the same elements as the old array is to use NSCopying or NSMutableCopying.
NSArray* myArray2 = [myArray1 copy]; // myArray2 is an immutable array
NSMutableArray* myArray3 = [myArray1 mutableCopy]; // myArray3 is an mutable array
If you want to print the contents of an array for debugging purposes:
NSLog(#"myArray2 = %#", myArray2);
If you want prettier printing for a UI, you'll need to iterate through as others have suggested.