i had 2 arrays with objects and the same nameobject should be cancelled only one time - iphone

I have input as two arrays shown below
NSArray *array1=[[NSArray alloc]initWithObjects:#"1",#"2",#"3", nil];
NSArray *array2=[[NSArray alloc]initWithObjects:#"1",#"2",#"1", nil];
the output should resemble like this.
the same element should be cancelled only one time.
NSArray *array3=[[NSArray alloc]initWithObjects:#"1",#"2", nil];
THANKS IN ADVANCE.....

NSArray *array1 = #[#"1",#"2",#"3"];
NSArray *array2 = #[#"1",#"2",#"1"];
NSMutableSet *allElemets = [NSSet setWithArray:array1];
[allElemets addObjectsFromArray:array2];
This will return you all elements without duplicates.
In this case it will be
#"1",#"2",#"3"
Edit:
This will return the intersection of the arrays
NSMutableSet *set1 = [NSMutableSet setWithArray:array1];
NSSet *set2 = [NSSet setWithArray:array2];
[set1 intersectSet:set2];

Use NSCountedSet for the above situation
NSMutableArray *array1=[[NSMutableArray alloc]initWithObjects:#"r",#"a",#"r",#"r",#"r", nil];
NSArray *array2=[[NSArray alloc]initWithObjects:#"b",#"c",#"r", nil];
NSMutableSet *setOne = [NSMutableSet setWithArray: array1];
NSSet *setTwo = [NSSet setWithArray: array2];
[setOne unionSet:setTwo];
NSArray *arrayOneResult = [setOne allObjects];
NSLog(#"%#",arrayOneResult);
NSMutableArray *resultArray = [[NSMutableArray alloc]init];
NSCountedSet *set = [[NSCountedSet alloc] initWithArray:arrayOneResult];
for (id item in set)
{
NSCountedSet *set1 = [[NSCountedSet alloc] initWithArray:array1];
NSCountedSet *set2 = [[NSCountedSet alloc]initWithArray:array2];
int diff = abs([set1 countForObject:item] - [set2 countForObject:item]);
for (int i = 0 ;i < diff ;i++ ) {
[resultArray addObject:item];
}
}
NSLog(#"the array : %#",resultArray );

f you are fine with sets instead of arrays, you can use NSMutableSet instead of NSArray. NSMutableSet has nice methods like intersectSet: and minusSet:

if([[array1 objectAtIndex:i] isEqualToString:[array2 objectAtIndex:i]])
{
[array2 removeObjectAtIndex: i];
NSLog(#"same element removed.");
}
array3 = [firstArray arrayByAddingObjectsFromArray:secondArray];
or
NSMutableSet *set = [NSMutableSet setWithArray:array1];
[set addObjectsFromArray:array2];
array3 = [set allObjects];
Two arrays are compared and duplicate values are removed, you get your values.

Here tHe Code goes
EDIt: This WOuld remove the Duplicate Value add Unique value.
NSArray *array1=[[NSArray alloc]initWithObjects:#"1",#"2",#"3", nil];
NSArray *array2=[[NSArray alloc]initWithObjects:#"1",#"2",#"1", nil];
//Here Create nEw Array with Arra1
NSMutableArray * newArray =[[NSMutableArray alloc] initWithArray:array1];
for(int index=0; index<[array2 count];index++)
{
id object =[array2 objectAtIndex:index];
if(![newArray containsObject:object])//this methods Returns YES/NO
{
[newArray addObject: object];
}
}

Related

Sort multiple values in arrays

I have an array with multiple locations for different states.
{"location":"Lekki Phase 1","state":"abc","country":"Nigeria"},
{"location":"Lekki Phase 2","state":"xyz","country":"Nigeria"},
{"location":"Osapa London1","state":"def","country":"Nigeria"},
{"location":"Lekki Phase 2","state":"abc","country":"Nigeria"},
{"location":"Lekki Phase 3","state":"xyz","country":"Nigeria"},
{"location":"Osapa London 2","state":"def","country":"Nigeria"},..........
Now i can make an array for different states with no duplicate state , like
{"abc","xyz","def"}
But what i want is to display all locations state wise in a table.
How can i do this??
Using NSPredicate we can efficiently filter this . I have tried and tested working for me.
Here 'allDataArray' is array with dictionaries, You can replace your array here (the first one in your post)
NSMutableArray *allDataArray = [[NSMutableArray alloc] init];
NSMutableDictionary *dict1 = [[NSMutableDictionary alloc] init];
[dict1 setObject:#"Lekki Phase 1" forKey:#"location"];
[dict1 setObject:#"abc" forKey:#"state"];
[dict1 setObject:#"Nigeria" forKey:#"country"];
[allDataArray addObject:dict1];
dict1 = [[NSMutableDictionary alloc] init];
[dict1 setObject:#"Lekki Phase 2" forKey:#"location"];
[dict1 setObject:#"xyz" forKey:#"state"];
[dict1 setObject:#"Nigeria" forKey:#"country"];
[allDataArray addObject:dict1];
dict1 = [[NSMutableDictionary alloc] init];
[dict1 setObject:#"Lekki Phase 2" forKey:#"location"];
[dict1 setObject:#"abc" forKey:#"state"];
[dict1 setObject:#"Nigeria" forKey:#"country"];
[allDataArray addObject:dict1];
dict1 = [[NSMutableDictionary alloc] init];
[dict1 setObject:#"Lekki Phase 3" forKey:#"location"];
[dict1 setObject:#"xyz" forKey:#"state"];
[dict1 setObject:#"Nigeria" forKey:#"country"];
[allDataArray addObject:dict1];
//NSLog(#"%#",allDataArray);
NSArray *state = [NSArray arrayWithObjects:#"abc",#"xyz", nil];
NSMutableArray *locationInState = [[NSMutableArray alloc] initWithCapacity:[state count]];
for(int i=0; i< [state count]; i++)
{
NSMutableArray *filteredarray = [[allDataArray filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"(state == %#)", [state objectAtIndex:i]]] mutableCopy];
for(int j=0; j<[filteredarray count];j++)
{
NSDictionary *dict = [filteredarray objectAtIndex:j];
[filteredarray replaceObjectAtIndex:j withObject:[dict valueForKey:#"location"]];
}
[locationInState addObject:filteredarray];
}
NSLog(#"%#",locationInState);
Here locationInState array contains all location for filetred state. You can map them easily by index.
Result is
(
(
"Lekki Phase 1",
"Lekki Phase 2"
),
(
"Lekki Phase 2",
"Lekki Phase 3"
)
)
First It not array but it is Dictionary.
NSMutableDictionary * newDict = [NSMutableDictionary dictionaryWithCapacity:[OLdDict count]];
for(id item in [OLdDict allValues]){
NSArray * keys = [OLdDict allKeysForObject:item];
[newDict setObject:item forKey:[[OLdDict allKeysForObject:item] objectAtIndex:0]];
}
NSMutableDictionaries can act as uniquing collections (because they replace objects for keys if the same key is used twice). We can also take advantage of the fact that NSString is generally a constant address location, and funnel each one of those dictionaries into an array. To unique out each array of dictionaries, it would be far easier to wrap them in an object, but here goes:
-(void)uniquingSort {
//Setup collections for the uniquing process
NSMutableArray *datasource = //...
NSMutableIndexSet *hits = [NSMutableIndexSet indexSet];
NSMutableDictionary *uniquingDict = #{}.mutableCopy;
//Setup an index for the indexed set
int idx = 0;
//iterate through the array of dictionaries
for (NSArray *arrOfDicts in datasource) {
//get the dictionary we want to unique against
NSDictionary *innerDict = arrayOfDicts[1];
//do we have a dupe? If so, add its index to the index set
if (uniquingDict[innerDict[#"state"]] != nil)
[hits addIndex:idx];
uniquingDict[innerDict[#"state"]] = innerDict[#"state"];
idx++;
}
//cut out all the hits till we are only uniqued for the "state" key
[datasource removeObjectsAtIndexes:hits];
}

NSArray with double entries

I have a NSArray with a lot of entries. But some of them are twice.
And i want that every entry is only once in the Array.
Have somebody an idea how i can do this?
This is how i've tried it:
NSSet *newsSet = [NSSet setWithArray:news];
newsOrte = [newsSet allObject];
In order to use NSSet effectively the object being stored must conform to the NSObject protocol and implement the hash (reference) and isEqual: (reference) methods.
Please ensure your object implements these methods.
Try this way
NSArray *array=[[NSMutableArray alloc]initWithObjects:#"A",#"B",#"A",#"C",#"A", nil];
NSMutableArray *arr=[NSMutableArray new];
for(id obj in array){
if (![arr containsObject:obj]) {
[arr addObject:obj];
}
}
array=arr;
NSLog(#"==> %#",array);
Also you can do in this way:
NSArray *array=[[NSMutableArray alloc]initWithObjects:#"A",#"B",#"A",#"C",#"A", nil];
NSMutableDictionary *dict=[[NSMutableDictionary alloc]initWithObjects:array forKeys:array];
array=[dict allKeys];
NSLog(#"==> %#",array);
Output :
==> (
A,
B,
C
)
Here is code
NSArray* originalArray = ... // However you fetch it
NSMutableSet* existingNames = [NSMutableSet set];
NSMutableArray* filteredArray = [NSMutableArray array];
for (id object in originalArray) {
if (![existingNames containsObject:[object name]]) {
[existingNames addObject:[object name]];
[filteredArray addObject:object];
}
}
originalArray = [NSArray arrayWithArray:filteredArray];
Hope it helps you..

Sorting two NSMutableArrays by 'nearest distance' first

I have two arrays, both full of NSString objects like this:
NSMutableArray *titles = [[NSMutableArray alloc] initWithObjects:#"Title1", #"Title2", #"Title3", #"Title4", #"Title5", nil];
NSMutableArray *distances = [[NSMutableArray alloc] initWithObjects:#"139.45", #"23.78", #"347.82", #"10.29", #"8.29", nil];
How can I sort both arrays by the nearest distance first?
So the results would be like this:
titles = #"Title5", #"Title4", #"Title2", #"Title1", #"Title3"
distances = #"8.29", #"10.29", #"23.78", #"139.45", #"347.82"
I understand that NSSortDescriptor can be used in these circumstances but after looking through the documentation, I am still unsure about how.
I would sort the distances this way...
NSNumberFormatter *f = [[NSNumberFormatter alloc] init];
[f setNumberStyle:NSNumberFormatterDecimalStyle];
NSArray *sortedDistances = [listItem sortedArrayUsingComparator: ^(id a, id b) {
NSNumber *aNum = [f numberFromString:a];
NSNumber *bNum = [f numberFromString:b];
return [aNum compare:bNum];
}];
I can't think of a particularly quick way to get the associated titles sorted, but this should work ...
NSMutableArray *sortedTitles = [NSMutableArray array];
NSDictionary *distanceTitle = [NSDictionary dictionaryWithObjects:titles forKeys:distances];
for (NSString *distance in sortedDistances) {
NSString *associatedTitle = [distanceTitle valueForKey:distance];
[sortedTitles addObject:associatedTitle];
}
You can use an NSComparator block and use NSArray's sortedArrayUsingComparator method. On that block, you will receive two objects to compare, and base on the comparison result, you can use NSMutableArray exchangeObjectAtIndex:withObjectAtIndex: method to change the values of titles.
Here is a sample how I sort an array of dictionaries by distance value:
-(void)reorderByDistance {
NSSortDescriptor *sortByName = [NSSortDescriptor sortDescriptorWithKey:#"distance" ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObject:sortByName];
self.contentArray = [self.contentArray sortedArrayUsingDescriptors:sortDescriptors];
}
And my dictionary looks like this:
NSDictionary *dict1 = [[NSDictionary alloc] initWithObjectsAndKeys:#"1", #"id", #"Business #1", #"name", #"This business does some pretty remarkable things", #"description", #"Alley Bar", #"category", #"1.2", #"distance", nil];
One approach would be to create a dictionary mapping titles to distances, sort the distances, and then iterate through the distances to recreate the titles:
NSMutableArray *titles = [[NSMutableArray alloc] initWithObjects:#"Title1", #"Title2", #"Title3", #"Title4", #"Title5", nil];
NSMutableArray *distances = [[NSMutableArray alloc] initWithObjects:#"139.45", #"23.78", #"347.82", #"10.29", #"8.29", nil];
//Create a map of current titles to distances
NSDictionary *titleDistanceMap = [NSDictionary dictionaryWithObjects:titles forKeys:distances];
//Need to sort the strings as numerical values
[distances sortUsingComparator:^(NSString *obj1, NSString *obj2) {
return [obj1 compare:obj2 options:NSNumericSearch];
}];
//Now re-populate the titles array
[titles removeAllObjects];
for (NSString *distance in distances){
[titles addObject:[titleDistanceMap objectForKey:distance]];
}

How to order NSMutableArray with NSMutableArray inside

I need so sort an array with an array inside, something like this:
NSMutableArray * array_example = [[NSMutableArray alloc] init];
[array_example addObject:[NSMutableArray arrayWithObjects:
string_1,
string_2,
string_3,
nil]
];
how can i order this array by the field "string_1" of the array???
any idea how can i do that?
Thanks
For iOS 4 and later, this is easily done using a comparator block:
[array_example sortUsingComparator:^(NSArray *o1, NSArray *o2) {
return (NSComparisonResult)[[o1 objectAtIndex:0] compare:[o2 objectAtIndex:0]];
}];
If you're interested in how blocks work, you can have a look at Apple's Short Practical Guide to Blocks.
If you wish to support iOS 3.x, you'd have to use a custom comparison function:
NSComparisonResult compareArrayFirstElement(NSArray *o1, NSArray *o2) {
return [[o1 objectAtIndex:0] compare:[o2 objectAtIndex:0]];
}
and then use:
[array_example sortUsingFunction:compareArrayFirstElement context:nil];
You can loop the array objects and call sortedArrayUsingSelector on each sub array, then replaceObjectAtIndex:withObject to inject back into the original array
NSMutableArray * array_example = [[NSMutableArray alloc] init];
[array_example addObject:[NSMutableArray arrayWithObjects:
#"z",
#"a",
#"ddd",
nil]
];
[array_example addObject:[NSMutableArray arrayWithObjects:
#"g",
#"a",
#"p",
nil]
];
NSLog(#"Original Array: %#", array_example);
for(int i = 0; i < [array_example count] ; i++){
[array_example replaceObjectAtIndex:i withObject:[[array_example objectAtIndex:i] sortedArrayUsingSelector:#selector(caseInsensitiveCompare:)]];
// order sub array
}
NSLog(#"Sorted Array: %#", array_example);

how to create an array of string or float in Objective-C

i need some help here, i need to know how to create an array of string retrieved from an array. i'm using powerplot for graph and it only accept float or string array.
i need to create something something like this dynamically.
NSString * sourceData[7] = {#"2", #"1", #"4", #"8", #"14", #"15", #"10"};
Below are my code to find out the numbers in strings.
NSInteger drunked = [appDelegate.drinksOnDayArray count];
NSMutableArray * dayArray = [[NSMutableArray alloc] init];
NSMutableArray * sdArray = [[NSMutableArray alloc] init];
//float *sdArray[7];
for (int i=0; i<drunked; i++) {
DayOfDrinks *drinksOnDay = [appDelegate.drinksOnDayArray objectAtIndex:i];
NSString * dayString= [NSDate stringForDisplayFromDateForChart:drinksOnDay.dateConsumed];
[dayArray addObject:dayString];
NSLog(#"%#",[dayArray objectAtIndex:i]);
drinksOnDay.isDetailViewHydrated = NO;
[drinksOnDay hydrateDetailViewData];
NSString * sdString= [NSString stringWithFormat:#"%#", drinksOnDay.standardDrinks];
[sdArray addObject:sdString];
NSString *tempstring;
NSLog(#"%#",[sdArray objectAtIndex:i]);
}
thanks for the help :)
Array's in Objectice-C aren't that hard to work with:
NSMutableArray *myArray = [NSMutableArray array];
[myArray addObject:#"first string"]; // same with float values
[myArray addObject:#"second string"];
[myArray addObject:#"third string"];
int i;
int count;
for (i = 0, count = [myArray count]; i < count; i = i + 1)
{
NSString *element = [myArray objectAtIndex:i];
NSLog(#"The element at index %d in the array is: %#", i, element); // just replace the %# by %d
}
You can either use NSArray or NSMutableArray - depending on your needs, they offer different functionality.
Following tutorial covers exactly what you are looking after:
http://www.cocoalab.com/?q=node/19
You can also add the elements to the array when you init (and optionally add them later only if you are using the Mutable version of a collection class:
NSMutableArray *myArray = [[NSMutableArray alloc] initWithObjects:#"2", #"1", #"4", #"8", #"14", #"15", #"10", nil];
[myArray addObject:#"22"];
[myArray addObject:#"50"];
//do something
[myArray release];
You can use malloc to create a C-style array. something like this should work:
NSString **array = malloc(numElements * sizeof(NSString *))
some code here
free(array)
Be aware that unlike NSMutable array, c arrays won't do a retain, so you have to manage it if needed. And don't forget the free