Sorting an array of dictionaries in Plist - objective-c

Trying to sort an array of dictionaries. There are two arrays in the plist file and I am trying to sort one of them and having a lot of trouble. I can extract the dictionaries into a NSArray and sort the files.
I can only do this by extracting the dictionaries so when I try to save the information back to the plist I've lost my structure and other array of dictionaries.
How can I sort the array correctly. I understand I'm extracting the array and then saving it as it's own file. I see what I'm doing wrong but can't figure how the correct way.
NSArray *array = [dict valueForKey:#"Lighting"];
NSSortDescriptor* nameSortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"Controller Zone" ascending:YES];
NSArray* sortedArray = [array sortedArrayUsingDescriptors:[NSArray arrayWithObject:nameSortDescriptor]];
NSString *pathToFileExportSorted = #"/Users/scott/Desktop/plistPreSEsorted.plist";
[sortedArray writeToFile:pathToFileExportSorted atomically: YES];
I have tried something like this but couldn't get that working either
[array sortUsingDescriptors:[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:#"Lighting.Controller Zone" ascending:YES]]];
I just want to sort the Array Lighting by "Controller Zone" and keep the plist as is otherwise.
Thanks for any help.
Original Data:
What I am currently Exporting, does not have Lighting and Shade array. The array is now the only thing in the plist.

it's needed to assign sorted array to Lighting key
...and to save your initial dictionary with changed Lighting key
NSArray *array = [dict valueForKey:#"Lighting"];
NSSortDescriptor *nameSortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"Controller Zone" ascending:YES];
NSArray *sortedArray = [array sortedArrayUsingDescriptors:[NSArray arrayWithObject:nameSortDescriptor]];
NSMutableDictionary *dictToSave = [[dict mutableCopy] autorelease];
[dictToSave setObject:sortedArray forKey:#"Lighting"];
NSString *pathToFileExportSorted = #"/Users/scott/Desktop/plistPreSEsorted.plist";
[dictToSave writeToFile:pathToFileExportSorted atomically:YES];
That should work as you've described.

Related

How to fetch data of NSString from array of structure hold by NSMutableArray in objective c?

I have one NSMutableArray tempArray = \[NSMutableArray array\]; which contains an array of structured objects with multiple data: brand_package_id , slide_master_id etc....
I want to sort out the tempArray according to slide_master_id's.
Please see given image and help me to sort this problem.
Try using NSSortDescriptor:
NSSortDescriptor *slideDescriptor = [[NSSortDescriptor alloc]
initWithKey:#"slide_master_id" ascending:YES];
NSArray *sortDescriptors = #[slideDescriptor];
NSArray *sortedArray = [tempArray sortedArrayUsingDescriptors:sortDescriptors];

Inserting NSDictionary into sorted NSMutableArray

I want to insert an NSDictionary object into an array and have the array sorted by objectForKey.
I managed to do this by inserting, re-sorting and reloading the array, which works fine, but I figured there would be a better method, which there is, I just don't know how to use it.
Current code:
-(NSMutableArray*)sortArray:(NSMutableArray*)theArray {
return [[theArray sortedArrayUsingDescriptors:[NSArray arrayWithObject:[[NSSortDescriptor alloc] initWithKey:#"n"
ascending:YES]]] mutableCopy];
}
returns the re-sorted array. Fine. Works perfectly, but... is it the most efficient?
From another question I gather that this is the method to use to find the index to insert into:
NSUInteger newIndex = [array indexOfObject:newObject
inSortedRange:(NSRange){0, [array count]}
options:NSBinarySearchingInsertionIndex
usingComparator:comparator];
[array insertObject:newObject atIndex:newIndex];
The problem is I have no idea how to use the comparator method, and if that's even possible when I want to sort by objectForKey for each index.
Can anyone exemplify the above method when the key of the object (newObject in above example) to sort by is, let's say:
[newObject objectForKey:#"sortByThis"];
Use NSSortDescriptor
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"sortByThisKey" ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
NSArray *sortedArray = [myArray sortedArrayUsingDescriptors:sortDescriptors];
here is the simple example for comparator
- (NSComparisonResult)compareResulst:(CustomObject *)otherObject {
if(self.name isEqualToString:key)
{
return NSOrderedAscending;
}
else
{
return NSOrderedDescending
}
}
NSArray *sArray;
sArray = [unsArray sortedArrayUsingSelector:#selector(compareResulst:)];
this will sort the array. it will iterate through object and based on your if else it will move object up and down ...
Here's an example of sorting
//For make a we're adding 5 random integers into array inform of NSDictionary
//here, we're taking "someKey" to store the integer (converted to string object) into dictionary
NSMutableArray *array = [NSMutableArray array];
for(int i = 1; i<=5; i++) {
[array addObject:[NSDictionary dictionaryWithObject:[#(arc4random()%10) stringValue] forKey:#"someKey"]];
}
//create a sort descriptor to sort the array
//give the key in dictionary for which you want to perform sort
NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:#"someKey" ascending:YES];
//we're doing self sort for mutable array, & that's it, you'll have a sorted array.
[array sortUsingDescriptors:#[sort]];
N.B.
1.Instead of "someKey" from above example you can set any key for which you want to perform sort.
2.There's some other methods for sorting, you can use the one base on your requirement.
3.see #[sort] in code. Its full version is, [NSArray arrayWithObject:sort];

Accessing descriptors in array of arrays

I have a mutable array containing some arrays for use in a table view controller. The arrays contain a title and some other information. I want the arrays in the master array to be sorted alphabetically in terms of the title they contain. I have assigned the titles with keys:
NSString *title = #"objectTitle";
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:_storedTitle.text, title, nil];
NSArray *newArray = #[#"Login", dict, _storedUsername.text, _storedPassword.text];
I store the newArray in my masterArray and try to sort the array thus:
//sort array alphabetically
NSSortDescriptor *titleDescriptor = [[NSSortDescriptor alloc] initWithKey:#"objectTitle" ascending:YES];
NSArray *sortDescriptors = #[titleDescriptor];
NSArray *sortedArray = [_masterArray sortedArrayUsingDescriptors:sortDescriptors];
_masterArray = sortedArray.copy;
This is not working, as i have not specified the index where the titleDescriptor is stored. How do I do this?
When accessing the title at a given index (index) in the master array is done as follows:
NSLog(#"%#", [[[_masterArray objectAtIndex:index] objectAtIndex:1] objectForKey:#"objectTitle"]);
Modified your code like this:-
NSSortDescriptor *sortedDescriptor =
[[[NSSortDescriptor alloc]
initWithKey:#"objecttitle"
ascending:YES
selector:#selector(localizedCaseInsensitiveCompare:)] autorelease];
NSArray * descriptors =
[NSArray arrayWithObjects:sortedDescriptor, nil];
NSArray * sortedArray =
[array sortedArrayUsingDescriptors:descriptors];
NSlog(#"%#",sortedArray);

How to sort an array which contains Dictionaries?

I have an array which contains dictionaries in it; so how can I sort the array according to dictionary key values?
If every element in the array is a dictionary containing a certain key, you can sort the array using a sort descriptor. For instance, if every element is a dictionary containing a key called "name":
NSSortDescriptor *sortByName = [NSSortDescriptor sortDescriptorWithKey:#"name"
ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObject:sortByName];
NSArray *sortedArray = [array sortedArrayUsingDescriptors:sortDescriptors];
The other way to achieve this would be using sortedArrayUsingComparator: method
NSArray *sortedArray = [array sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
return [[obj1 valueForKey:#"value"] compare:[obj2 valueForKey:#"value"]];
}];
why don't you use a sorted dictionary where the property of sorted elements comes already with the data structure?
Please do check it out here
Hope this helps.
The above shared answer by Bavarious helped me.Just want to add one more thing.If you want to sort a mutable array use something like the below code
NSSortDescriptor *sortByName = [NSSortDescriptor sortDescriptorWithKey:#"name" ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObject:sortByName];
NSMutableArray *sortedArray = [[NSMutableArray sortedArrayUsingDescriptors:sortDescriptors]mutableCopy];
let arrDescriptor = NSSortDescriptor(key: "order", ascending: true)
let sortDescriptors: NSArray = [arrDescriptor]
let sortedArray = instancesubArray.sortedArray(using: sortDescriptors as [AnyObject] as [AnyObject] as! [NSSortDescriptor])
print(sortedArray)

Quicksort to order array by business key?

I've an array of objects, the size of which I cannot predict. The contents of the array are model objects with properties of type nsstring and nsnumber.
I need to sort the array according to one of the properties, an nsnumber. How would you do it in objective-c/Cocoa? Implement quicksort or some other algorithm (which one)? Any libraries that handle that for you?
Update
While the response below is correct, it only works on 10.6 and I'm targeting 10.5.
NSArray has several sorting methods. Given your array, arr,
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:#"numberProperty" ascending:YES];
NSArray *sortedArr = [arr sortedArrayUsingSortDescriptors:[NSArray arrayWithObject:sortDescriptor]];
will give you an array sorted (ascending) by #"numberProperty". Obviously, you'll have to substitute the name of the NSNumber property in your model objects for #"numberProperty".
The sorting algorithm is not specified in NSArray's sorting methods.
This is what I came up with:
NSArray *unsortedArray = [results allValues];
NSSortDescriptor *sortDescriptor = [[[NSSortDescriptor alloc]
initWithKey:#"ordinalPosition"
ascending:YES]
autorelease];
NSArray *sortedArray = [unsortedArray
sortedArrayUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]];
Use qsort() from stdlib.h.