Create NSArray with specific property - ios

I have an NSArray called carparkArr that contain MyCarpark objects. This class contain:
#property (nonatomic, assign) CLLocationCoordinate locationCoord;
Now I want to create an array that will have NSValue of each of these objects. How to do it quickly? I want something like:
NSArray *carparkArr = // fetching data
NSArray *locationProperty = [self getArrayForPropertyPath:#".locationCoord" forArray:carparkArr];

Yeah that feature already exists:
NSArray *locationProperty = [carparkArr valueForKey:#"locationCoord"];

Related

NSSet with string property from array of objects

I have an array of somethings, I'd like to make a set from an NSString property on this object:
#protocol something<NSObject>
#property(nonatomic, readonly) NSString *Id;
#end
I have an array of somethings:
NSArray<id<something>> *arrayOfSomethings;
I'd like to get a NSSet of the Id properties:
NSSet<NSString *> *idSet = ?; // Calculate from arrayOfSomethings.
How do I do this? Thanks
You can use valueForKey: to create an array that contains your ids and then use that to create an NSSet
NSSet<NSString *> *idSet = [NSSet setWithArray:[arrayOfSomethings valueForKey:#"id"]];

How to sort NSArray items into groups based on the same object order in a different NSArray? [duplicate]

This question already has answers here:
Sort NSArray of custom objects based on sorting of another NSArray of strings
(5 answers)
Closed 7 years ago.
I have an NSArray of unique UUIDs sorted in the proper order. I also have another NSArray of bookmarks with a UUID encoding. I would like to sort my NSArray of bookmarks based on their UUID property into groups.
For example, I have an NSArray: #[#"uuid1", #"uuid3", #"uuid2"] that has been sorted into this particular order. Now the other NSArray must sort all of its bookmarks in the same order as the first NSArray above.
So the second NSArray is: #[#"bookmark1", #"bookmark2", #"bookmark3", ...etc.]
Say bookmark 1 has the UUID property encoded as uuid2, bookmark 2 has the UUID encoding of uuid 1, but the bookmark 3 has encoding of uuid3. How can I sort and group these bookmarks so that it would be: #[#"bookmark2", #"bookmark3", #"bookmark1"]?
Thanks!
You could get rid of the second array and use a dictionary instead, which is keyed on the UUID.
NSArray *sortedIDs = #[ #"uuid1", #"uuid3", #"uuid2", ];
NSDictionary *items = #{
#"uuid1" : #[ bookmark1 ],
#"uuid2" : #[ bookmark2 ],
#"uuid3" : #[ bookmark3 ],
};
Now when you want the second bookmark you can access it with
NSArray *bookmarksForUUID = items[sortedIDs[1]];
If you wanted to build the structure above you could add a category like the below to NSArray
- (NSDictionary *)pas_groupBy:(id (^)(id object))block;
{
NSParameterAssert(block);
NSMutableDictionary *groupedDictionary = NSMutableDictionary.new;
for (id object in self) {
id key = block(object);
if (groupedDictionary[key]) {
[groupedDictionary[key] addObject:object];
} else {
groupedDictionary[key] = [NSMutableArray arrayWithObject:object];
}
}
return groupedDictionary;
}
Then assuming your bookmark objects look something like
#interface Bookmark : NSObject
#property (nonatomic, copy) NSString *UUID;
// other properties
// other properties
#end
You can use the category like this
NSDictionary *bookmarksMappedBySection = ({
return [bookmarks pas_groupBy:^(Bookmark *bookmark) {
return bookmark.UUID;
};
});
Create a class Bookmark. Add both the UUIDs and title as properties to this class. Now you can have just one array which holds objects of class Bookmark and each one will have access to its UUID and title (as well as any other properties you might want to add later on).
#interface Bookmark: NSObject
#property (nonatomic,strong) NSString *uuid;
#property (nonatomic,strong) NSString *title;
#end
Now if you have NSArray (lets call it myBookmarks) you can do the following:
for (Bookmark *bookmark in myBookmarks) {
NSLog(#"my UUID is %#",bookmark.uuid);
NSLog(#"my title is %#",bookmark.title);
}
If you need to store these items in NSUserDefaults all you have to do is adopt the NSCoding protocol. If you don't know how to do it here is a great and simple example.

How can I access an NSMutableArray in a different class?

I declare the following in ViewController.h
#property (nonatomic, strong) NSMutableArray *locations;
and the following in ViewController.m
#implementation GHViewController
#synthesize locations;
...
for (FSFourSquareVenueObject *object in array) {
locations = [[NSMutableArray alloc] init];
[locations addObject:object.locationName];
NSLog(#"%#", locations);
}
This successfully logs all the string locations that have been placed in the locations NSMutableArray. How can I access this NSMutableArray in a different class?
I am trying to access it in my TableViewController class in order to display all the elements in the array. I have tried importing the ViewController.h file into my TableViewController.h file, yet I still cannot access the array from the ViewController class.
Remove the line
locations = [[NSMutableArray alloc] init];
from your for loop and place it somewhere like viewDidLoad or init. You're wiping out your array every time before adding a new object.
To access a single object across classes, you want to look into creating a singleton. There are many tutorials online.
Do as #Stonz2 suggests, but also modify your headers as follows:
In GHViewController.h:
#property (nonatomic, strong) NSArray *locations;
In GHViewController.m
#implementation GHViewController
#synthesize locations;
...
NSMutableArray *array = [[NSMutableArray alloc] init];
for (FSFourSquareVenueObject *object in array) {
[array addObject:object.locationName];
NSLog(#"%#", array);
}
self.locations = [array copy];
You can then access the array from another class using GHViewController -locations. You can edit the locations using the following snippet (or by creating a similar method in GHViewController):
NSMutableArray *array = [gh_viewController.locations mutableCopy];
[array addObject: newLocation];
gh_viewController.locations = [array copy];
Exposing a mutable array allows other class to modify the array without notifying GHViewController and vice versa. This can lead to unpredictable and hard to debug problems, such as if GHViewController removes some elements while TableViewController is iterating through all the objects. Using a non-mutable array prevents these sorts of bugs and ensures everyone has a consistent view of what's inside.

Remove Duplicate Objects From NSMutableArray object property? [duplicate]

This question already has answers here:
How to remove all objects with the same property value but one in NSMutableArray
(3 answers)
Closed 9 years ago.
I have one NSObject with properties as following
#property (nonatomic, retain) NSString * destinationid;
#property (nonatomic, retain) NSString * destinationname;
#property (nonatomic, retain) NSString * assetid;
#property (nonatomic, retain) NSString * assetname;
#property (nonatomic, retain) NSString * assetdescription;
Here, I save this in NSMutableArray.
The data which I get from server contains same DestinationName, but different other properties.
I want to check, if same name of Object is already added to NSMutableArray, don't add it again.
I tried to user innner loops but no use :(
Thanks
Here's one solution:
NSArray *originalArray = ... // original array of objects with duplicates
NSMutableArray *uniqueArray = [NSMutableArray array];
NSMutableSet *names = [NSMutableSet set];
for (id obj in originalArray) {
NSString *destinationName = [obj destinationname];
if (![names containsObject:destinationName]) {
[uniqueArray addObject:obj];
[names addObject:destinationName];
}
}
One way to do it is to create a new array that only contains the destination names from your other array, and check if the name from your server is contained there:
NSArray *names = [self.mut valueForKey:#"destinationname"];
if (![names containsObject:destName]) {
[self.mut addObject:newObjectFromServer];
}
mut is the name of my mutable array, and destName is the destination name in the object your getting from the server.
This function should do the job:
BOOL contains(id object, NSMutableArray *array)
{
for (id array in yourArray)
if ([object.destinationname isEqualToString:yourObject.destinationname])
return YES;
return NO;
}
Usage example:
if (!contains(object, array))
[array addObject:object];

Subtract an array of complex objects from another array of same kind of objects ios

I know that subtracting an NSArray from NSArray if it is a single basic object found here
But what i have is an object like this
#interface Set : NSObject
#property (nonatomic, strong) NSString *ItemId;
#property (nonatomic, strong) NSString *time;
#property (nonatomic, strong) NSString *Category_id;
#property (nonatomic, strong) NSString *List_id;
#property (nonatomic, strong) NSString *name;
#end
How can i delete an array having the set object from another array with the same?
It can be done by iterations that i knw.Is there some other way ?
EDIT: For clarity
I have Array A with 5 Set objects and I have 4 Set Objects in Array B
array A and Array B contain 3 set objects with common values..[Note : memory may be different] common
All I need is an Array C =Array A - Array B that has 2 objects in resulting array C
Thank You :)
You need to implement the - (NSUInteger)hash and - (BOOL)isEqual:(id)object method in Set class.
For eg:-
- (NSUInteger)hash {
return [self.ItemId hash];
}
- (BOOL)isEqual:(id)object
{
return ([object isKindOfClass:[self class]] &&
[[object ItemId] isEqual:_ItemId])
}
After that try this:
NSMutableSet *set1 = [NSMutableSet setWithArray:array1];
NSMutableSet *set2 = [NSMutableSet setWithArray:array2];
[set1 intersectSet:set2]; //this will give you only the obejcts that are in both sets
NSArray *commonItems = [set1 allObjects];
[mutableArray1 removeObjectsInArray:commonItems];//mutableArray1 is the mutable copy of array1
mutableArray1 will have all objects in the same order as earlier after removing common objects.
By using NSSet and NSPredicate we can meet your requirement.
Assessors *ass1 = [[Assessors alloc] init];
ass1.AssessorID = #"3";
Assessors *ass2 = [[Assessors alloc] init];
ass2.AssessorID = #"2";
Assessors *ass3 = [[Assessors alloc] init];
ass3.AssessorID = #"1";
Assessors *ass4 = [[Assessors alloc] init];
ass4.AssessorID = #"2";
NSSet *nsset1 = [NSSet setWithObjects:ass1, ass2, nil];
NSSet *nsset2 = [NSSet setWithObjects:ass3, ass4, nil];
// retrieve the IDs of the objects in nsset2
NSSet *nsset2_ids = [nsset2 valueForKey:#"AssessorID"];
// only keep the objects of nsset1 whose 'id' are not in nsset2_ids
NSSet *nsset1_minus_nsset2 = [nsset1 filteredSetUsingPredicate:[NSPredicate predicateWithFormat:#"NOT AssessorID IN %#",nsset2_ids]];
for(Assessors *a in nsset1_minus_nsset2)
NSLog(#"Unique ID : %#",a.AssessorID);
Here Assessors is my NSObject Class (Set in your case) and AssessorID is one property of that class.
Hope this can help.

Resources