Compare two arrays and set an if else - ios

I need to compare two arrays (A & B), than for the elements of A that belong also to B I need to set an if statement. Just to explain me better:
if (elementOfArrayA belong AlsoToarrayB) {
//do something
}else{
//do something else
}
Someone could help me?
Thanks

NSArray has an instance method called containsObject: exactly for this.
For further clarification, check this out.

Use following code to compare two array :
NSArray *array1 = [[NSArray alloc] initWithObjects:#"a",#"b",#"c",nil];
NSArray *array2 = [[NSArray alloc] initWithObjects:#"a",#"d",#"c",nil];
for(int i = 0;i<[array1 count];i++)
{
for(int j= 0;j<[array2 count];j++)
{
if([[array1 objectAtIndex:i] isEqualToString:[array2 objectAtIndex:j]])
{
} else {
}
}
}

Comparing two arrays:
if([arrayA isEqualToArray:arrayB]){
//the two arrays A and B are equals
}
The code above will test ALL elements of both arrays to check if they fulfill the isEqual test, so no need to for loop the array.
If you want to check wether an element of arrayA is contained in arrayB, use the following method:
id firstCommonObject = [arrayA firstObjectCommonWithArray:arrayB];
if(firstCommonObject != nil){
//a common object between arrayA and arrayB has been found
}else{
//no common objects between both arrays
}

// Method 1 - Simplest method to solve above problem (Use NSArray's containsObject method)
NSArray *array1 = [[NSArray alloc] initWithObjects:#"a",#"b",#"c",#"e", nil];
NSArray *array2 = [[NSArray alloc] initWithObjects:#"a",#"d",#"c",#"f", nil];
for(id i in array1){
if ([array2 containsObject:i]) {
// do something
}
else {
// do something else
}
}
// Method 2 - Another method (Use NSString's isEqualToString method)
NSArray *array1 = [[NSArray alloc] initWithObjects:#"a",#"b",#"c",#"e", nil];
NSArray *array2 = [[NSArray alloc] initWithObjects:#"a",#"d",#"c",#"f", nil];
for(id i in array1){
for(id j in array2){
if ([i isEqualToString:j]) {
// do something
}
else {
//do something else
}
}
}

it may be help you...
-(void)methodFour
{
NSArray *arr1 = [[NSArray alloc]initWithObjects:#"a2223a",#"ab33b",#"a1acdf",#"ac23c45", nil];
NSArray *arr11 = [arr1 sortedArrayUsingSelector:#selector(localizedCompare:)];
NSLog(#"%#",arr11);
NSArray *arr2 = [[NSArray alloc]initWithObjects:#"ab33b",#"ac23c45",#"a1acdf",#"a2223a", nil];
NSArray *arr22= [arr2 sortedArrayUsingSelector:#selector(localizedCompare:)];
[self firstArray:arr11 secondArray:arr22];
}
-(void)firstArray:(NSArray *)array1 secondArray:(NSArray *)array2
{
if ([array1 isEqualToArray:array2])
{
NSLog(#"equal");
}
else
{
NSLog(#"Not equal");
}
}

Related

Removing Duplicate Custom Objects from two arrays and combining them

First off i have searched a lot but all methods seems to be for primitives or for whole custom objects.
My situation is this. I have a type custom objects in two different arrays. However the fields of every single objects is quite different to another with the exception of only 2 fields.
What i want is combine both of these arrays and then remove duplicates with respect to only those two fields.How can i do that. My Code so far
NSMutableArray* testArray = [eventHandler returnAllEvents];
NSMutableArray* combinedArray = [[NSMutableArray alloc]init];
NSArray* finalArray = [[NSArray alloc]init];
if (testArray.count==0) {
for (int i = 0; i<facebookData.count; i++) {
LSEvent* event = [facebookData objectAtIndex:i];
[combinedArray addObject:event];
}
finalArray = [combinedArray arrayByAddingObjectsFromArray:calendarData];
}
NSMutableArray *uniqueArray = [NSMutableArray array];
NSMutableSet *names = [NSMutableSet set];
for (id obj in finalArray) {
NSString *destinationName = [obj destinationname];
if (![names containsObject:destinationName]) {
[uniqueArray addObject:obj];
[names addObject:destinationName];
}
}
You can do sth like this
NSArray first = ...
NSMutableArray second = ... // this will be combine array
for (id someObj in first) {
if ( [second filteredArrayUsingPredicate:[self predicateForObject:someObj ]].count == 0 ){
[second addObject: someObj];
}
}
If you want to check that object exists in array using containsObject: you need to implement - (BOOL)isEqual:(id)other in your custom object.
- (BOOL)isEqual:(id)other {
if (other == self) {
return YES;
}
if (!other || ![other isKindOfClass:[self class]]) {
return NO;
}
if (self.identifier == other.identifier) {
return NO;
}
return YES;
}

How to get all dictionaries with some same attributes from an array to a new array?

Here is my requirement :
forSaleSingleProperties array should contain dictionaries with no same attribute PARCELID
forSaleMultipleProperties array should contain an array of those dictionaries with same attribute PARCELID
forSalePropertiesArray is the base array containing all dict.
Note: Dictionaries contain various other attributes. I want all those with same PARCELID attribute
I don't understand what is wrong with this logic...
if (_forSaleSinglePropertiesArray==nil) {
_forSaleSinglePropertiesArray = [[NSMutableArray alloc]initWithObjects: nil];
}
if (_forSaleMultiplePropertiesArray==nil) {
_forSaleMultiplePropertiesArray = [[NSMutableArray alloc]initWithObjects: nil];
}
if (_forSalePropertiesArray!=nil) {
if (_forSalePropertiesArray.count>1) {
BOOL propertyObject1IsMultiple = NO;
NSDictionary *propertyObject1;
NSMutableArray *multiplePinArray = [[NSMutableArray alloc]initWithObjects: nil];
for (int i=0; i<_forSalePropertiesArray.count; i++) {
propertyObject1 = [_forSalePropertiesArray objectAtIndex:i];
multiplePinArray = nil;
multiplePinArray = [[NSMutableArray alloc]initWithObjects: nil];
for (int j=i+1; j<_forSalePropertiesArray.count; j++) {
NSDictionary *propertyObject2 = [_forSalePropertiesArray objectAtIndex:j];
if ([propertyObject1 valueForKey:PARCEL_ID]==[propertyObject2 valueForKey:PARCEL_ID]) {
if (_forSaleMultiplePropertiesArray.count==0) {
[multiplePinArray addObject:propertyObject2];
propertyObject1IsMultiple = YES;
[_forSaleMultiplePropertiesArray addObject:multiplePinArray];
}else{
BOOL propFound = NO;
NSMutableArray *propArr;
NSInteger index = -1;
for(NSMutableArray *arr in _forSaleMultiplePropertiesArray){
if (![arr containsObject:propertyObject2]&&!propFound) {
[arr addObject:propertyObject2];
propertyObject1IsMultiple = YES;
propFound = YES;
index = [_forSaleMultiplePropertiesArray indexOfObject:arr];
propArr = [[NSMutableArray alloc]initWithArray:arr];
}
}
if (propArr!=nil) {
[_forSaleMultiplePropertiesArray replaceObjectAtIndex:index withObject:propArr];
}
}
}
}
if (!propertyObject1IsMultiple) {
[_forSaleSinglePropertiesArray addObject:propertyObject1];
}
}
}
}
OK so...
I'm leaving this as a placeholder.
Sort the parent array by PARCELID.
Iterate array.
Sort into two piles.
... or something. Will write it later.
I would have done it more like this:
- (void)solution {
self.forSaleSinglePropertiesArray = [[NSMutableArray alloc] init];
self.forSaleMultiplePropertiesArray = [[NSMutableArray alloc] init];
NSDictionary *partitionedProperties = partitionPropertiesByParcelID(self.forSalePropertiesArray);
[self dividePropertiesIntoSingleAndMultiple:partitionedProperties];
}
NSDictionary *partitionPropertiesByParcelID(NSArray *properties) {
NSMutableDictionary *result = [[NSMutableDictionary alloc] init];
for (NSDictionary *property in properties) {
id parcelID = property[PARCEL_ID];
NSMutableArray *parcels = result[parcelID];
if (parcels == nil) {
parcels = [[NSMutableArray alloc] init];
[result setObject:parcels forKey:parcelID];
}
[parcels addObject:property];
}
return result;
}
- (void)dividePropertiesIntoSingleAndMultiple:(NSDictionary *)partitionedProperties {
for (NSArray *properties in partitionedProperties.allValues) {
if (properties.count == 1) {
[self.forSaleSinglePropertiesArray addObject:properties[0]];
}
else {
assert(properties.count > 1);
[self.forSaleMultiplePropertiesArray addObject:properties];
}
}
}
First the code creates a Dictionary where the keys are parcel IDs and the values are arrays of properties with that parcle ID. Then it goes through that dictionary and puts a representative of each parcel ID into either the single or multiple array.
I feel that this code is easier to understand, and I strongly suspect that if you do performance metrics on the above code and your answer, that this code will have better performance over large data sets. I believe this is true because your answer seems to have O(n^2) performance while mine is O(n). (Read up on "Big-O notation" if you aren't sure what this means.)
Also, are you sure that your answer actually works for all data sets? Removing objects out of an array while iterating over it throws up a huge red flag in my book.
I liked #Fogmeister's sort idea so much, I implemented it:
- (void)sortSolultion {
self.forSaleSinglePropertiesArray = [[NSMutableArray alloc] init];
self.forSaleMultiplePropertiesArray = [[NSMutableArray alloc] init];
NSArray *forSaleArray = [self.forSalePropertiesArray sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
return [obj1[PARCEL_ID] compare:obj2[PARCEL_ID]];
}];
id currentParcelID = nil;
self.propertiesWithCurrentParcelID = [[NSMutableArray alloc] init];
for (NSDictionary *property in forSaleArray) {
if (self.propertiesWithCurrentParcelID.count == 0) {
currentParcelID = property[PARCEL_ID];
}
else if (![property[PARCEL_ID] isEqual: currentParcelID]) {
[self placeCurrentPropertiesInCorrectArray];
currentParcelID = property[PARCEL_ID];
}
[self.propertiesWithCurrentParcelID addObject:property];
}
[self placeCurrentPropertiesInCorrectArray];
}
- (void)placeCurrentPropertiesInCorrectArray {
if (self.propertiesWithCurrentParcelID.count > 1) {
[self.forSaleMultiplePropertiesArray addObject:self.propertiesWithCurrentParcelID];
}
else if (self.propertiesWithCurrentParcelID.count == 1) {
[self.forSaleSinglePropertiesArray addObject:self.propertiesWithCurrentParcelID[0]];
}
[self.propertiesWithCurrentParcelID removeAllObjects];
}
This solution has a slightly higher cyclomatic complexity than my previous solution, and indeed it was harder to get it error free than my first one. But this solution has a smaller allocation footprint. Both seem to have the same big-O complexity.
Alright I got it right myself.
Updated Code to a much simpler and fast mechanism below:
if (_forSaleSinglePropertiesArray==nil) {
_forSaleSinglePropertiesArray = [[NSMutableArray alloc]initWithObjects: nil];
}
if (_forSaleMultiplePropertiesArray==nil) {
_forSaleMultiplePropertiesArray = [[NSMutableArray alloc]initWithObjects: nil];
}
if (_forSalePropertiesArray!=nil) {
NSMutableDictionary *samePropsDict = [[NSMutableDictionary alloc]init];
for (NSDictionary* dict in _forSalePropertiesArray) {
NSMutableArray *samePropsArray = [samePropsDict objectForKey:[dict valueForKey:PARCEL_ID]];
if (samePropsArray==nil) {
samePropsArray = [[NSMutableArray alloc]init];
}
[samePropsArray addObject:dict];
[samePropsDict setObject:samePropsArray forKey:[dict valueForKey:PARCEL_ID]];
}
for (NSString *key in [samePropsDict allKeys]) {
NSArray *arr = [samePropsDict objectForKey:key];
if (arr.count>1) {
[_forSaleMultiplePropertiesArray addObject:arr];
}else{
[_forSaleSinglePropertiesArray addObject:[arr firstObject]];
}
}
}

iOS: value not coming as String?

In my code, I set array inside a NSMutableDictionary as
if (array.count > 0) {
[self.filters setValue:array forKey:[self getKey:[[NSNumber numberWithInt:indexPath.section] intValue]]];
}
where array is
NSMutableArray *array = [[NSMutableArray alloc] init];
When the receiving code receives it, I tried to join the values in array as
if ([item objectForKey:#"category_filter"] != nil) {
NSArray *array = [NSArray arrayWithObjects:[item objectForKey:#"category_filter"], nil];
NSString *categories = [array componentsJoinedByString:#","];
NSLog(#"value:%#", categories);
}
where item is (NSMutableDictionary *)item
When I see log, I see as
2014-06-24 17:43:12.520 yelp[69744:70b] value:(
"Bagels (bagels)",
"Bakeries (bakeries)"
)
so they are not joined yet. What am I doing wrong here?
As Hot Licks commented,
I had to make change as
NSArray *array = [NSArray arrayWithArray:[item objectForKey:#"category_filter"]];
instead of
NSArray *array = [NSArray arrayWithObjects:[item objectForKey:#"category_filter"]];

Getting only one value when appending NSString to NSArray

Below is my code. When Looping over an NSArray of NSDictionary objects and trying to append to an array I keeping an NSLog which shows the correct result, but the result NSArray only contains the last record.
for (NSDictionary *entry in entries) {
NSString* projID = [entry objectForKey:#"NM_PROJECT"];
NSArray *projectNames = [[NSArray alloc] initWithObjects:projID,nil];
_projectpicker.delegate = self;
_projectpicker.dataSource = self;
NSLog(#"Error : %#", projID);
}
Log Result:
Test1
test2
test3
test4
When appending to NSArray (Projectnames) I was getting last data..
Every each loop iteration you initialise new array, you don't add new object to the array.
To do that you have to create NSMutableArray before loop and add object inside loop:
NSMutableArray *projectNames = [[NSMutableArray alloc] init];
for (NSDictionary *entry in entries) {
NSString* projID = [entry objectForKey:#"NM_PROJECT"];
[projectNames addObject: projID];
_projectpicker.delegate = self;
_projectpicker.dataSource = self;
NSLog(#"Error : %#", projID);
}
NSLog(#"Array : %#", projectNames);
Keep alloc statement outside of your for loop and use a NSMutableArray and then keep on adding to this array as and when required from inside the for loop.
NSMutableArray *projectNames = [[NSMutableArray alloc] init];
for(...)
{
[projectNames addObject: anyObject];
}
Setting:
_projectpicker.delegate = self;
_projectpicker.dataSource = self;
inside a loop doesn't make much sense. You don't need to do it multiple times.
While the other answers accurately describe what you're doing wrong with the array, your current requirement can be achieved more succinctly using KVC:
NSArray *projectNames = [entries valueForKey:#"NM_PROJECT"];
(then you don't need your own loop at all)

Is there anything like D3's Nest functionality in Objective-C?

Nesting means taking an array of key value pairs and grouping them hierarchically by a specified key. See this page for examples: http://bl.ocks.org/d/3176159/. If not, I'll just try to port https://github.com/mbostock/d3/blob/master/src/core/nest.js over but I don't want to reinvent the wheel.
This is the answer that I came up with. Let me know if you have suggestions for improvements.
// Wrapper method
// keys are in order of hierarchy
- (NSMutableArray *)nestArray:(NSArray *)array withKeys:(NSArray *)keys
{
return [self nestArray:array withKeys:keys depth:0];
}
// Private
// Assumes arrays of dictionaries with strings as the entries.
- (NSMutableArray *)nestArray:(NSArray *)array withKeys:(NSArray *)keys depth:(int)depth
{
// Current key
NSString *key = [keys objectAtIndex:depth];
depth++;
// Create dictionary of the keys
NSMutableDictionary *map = [[NSMutableDictionary alloc] init];
for (NSDictionary *dictionary in array) {
NSString *value = [dictionary objectForKey:key];
if ([map objectForKey:value]) {
[[map objectForKey:value] addObject:dictionary];
} else {
[map setObject:[NSMutableArray arrayWithObject:dictionary] forKey:value];
}
}
NSMutableArray *nest = [[NSMutableArray alloc] init];
for (NSString *valkey in [map allKeys]) {
NSMutableArray *values = [map objectForKey:valkey];
if (depth < keys.count) {
values = [self nestArray:[NSArray arrayWithArray:array] withKeys:keys depth:depth];
}
NSMutableDictionary *dictionary = [NSMutableDictionary dictionaryWithObjectsAndKeys:valkey,#"key",values,#"values", nil];
[nest addObject:dictionary];
}
return nest;
}

Resources