NSArray A = #[[[#"id":#"3"]], [[#"id":#"4"]] ,[[#"id":#"c"]],[[#"id":#"f"]]];
NSArray idArray = #[#"c", #"3", #"4",#"f"];
Just a example I assumed.
How can I sort A by its id with idArray?
That is, I want A to become:
NSArray A= #[[[#"id":#"c"]], [[#"id":#"3"]] ,[[#"id":#"4"]],[[#"id":#"f"]]];
Now, I want to ask for an algorithm to sort array A to get the desired result.
---I get my answer when I search in google:
NSArray *sorter = #[#"B", #"C", #"E"];
NSMutableArray *sortee = [#[
#[#"B", #"abc"],
#[#"E", #"pqr"],
#[#"C", #"xyz"]
] mutableCopy];
[sortee sortUsingComparator:^(id o1, id o2) {
NSString *s1 = [o1 objectAtIndex:0];
NSString *s2 = [o2 objectAtIndex:0];
NSInteger idx1 = [sorter indexOfObject:s1];
NSInteger idx2 = [sorter indexOfObject:s2];
return idx1 - idx2;
}];
If you want to compare both array you can use
NSArray *array1=#[#"3",#"4",#"c","f"];
NSArray *array2=#[#"c",#"3",#"4","f"];
array1=[array1 sortedArrayUsingSelector:#selector(compare:)];
array2=[array2 sortedArrayUsingSelector:#selector(compare:)];
if ([array1 isEqualToArray:array2]) {
NSLog(#"both are same");
}
else{
NSLog(#"both are differnt");
}
or If you want to get common elements from 2 array use
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* result = [set1 allObjects];
This would be a better way to make a dictionary for A. And then sorting based on their specific values like IQ, Name etc.
NSArray A = #[[[#"id":#"3"]], [[#"id":#"4"]] ,[[#"id":#"c"]],[[#"id":#"f"]]];
NSArray idArray = #[#"c", #"3", #"4",#"f"];
NSMutableArray *array = [NSMutableArray array];
for (int id = 0;idx<[A count];id++) {
NSDictionary *dict = #{#"Name": A[id],#"IQ":idArray[id]};
[array addObject:dict];
}
NSSortDescriptor *descriptor = [NSSortDescriptor sortDescriptorWithKey:#"IQ" ascending:NO];
[array sortUsingDescriptors:#[descriptor]]
Related
I have 2 arrays:
Array one: (#"26", #"26", #"25", #"25", #"3", #"3", #"4", #"4")
Array two: (#"sticker", #"sticker", #"sticker", #"sticker", #"sticker", #"frame", #"frame", #"frame")
Edit
These 2 arrays are connected like this:
26 - sticker
26 - sticker
25 - sticker
25 - sticker
3 - frame
3 - frame
4 - frame
4 - frame
I'm getting unique value in array one and putting it in another array like this:
NSArray *uniqueArrayOne = [[NSSet setWithArray:arrayOne] allObjects];
So uniqueArrayOne looks like this:
(26, 25, 3, 4)
I want uniqueArrayTwo to also be arrange like how uniqueArrayOne was arranged. I want uniqueArrayTwo to look like this:
(sticker, sticker, frame, frame)
What do I do?
Edit
Here is another example:
Array one: (#"TONY", #"SANSA", #"BILL", #"BILL", #"STEVE", #"STEVE")
Array two: (#"STARK", #"STARK", #"GATES", #"GATES", #"JOBS", #"JOBS")
The results should be like this:
uniqueArrayOne :(TONY, SANSA, BILL, STEVE)
uniqueArrayTwo :(STARK, STARK, GATES, JOBS)
uniqueArrayTwo is arrange depending on uniqueArrayOne.
I would solve it this way
- (void)uniqueArrayFinder
{
NSArray *array1 = [[NSArray alloc] initWithObjects:
#"TONY", #"SANSA", #"BILL", #"BILL", #"STEVE", #"STEVE",nil];
NSArray *array2 = [[NSArray alloc] initWithObjects:
#"STARK", #"STARK", #"GATES", #"GATES", #"JOBS", #"JOBS",nil];
NSMutableArray *combinedArray = [[NSMutableArray alloc] init];
for (int i=0; i<[array1 count];i++)
{
NSString *arrayVal1 = [array1 objectAtIndex:i];
NSString *arrayVal2 = [array2 objectAtIndex:i];
NSString *combinedStr = [NSString stringWithFormat:#"%# %#", arrayVal1, arrayVal2];
[combinedArray addObject:combinedStr];
}
//this gives uniqe values
NSSet *uniqueEvents = [NSSet setWithArray:combinedArray];
[combinedArray removeAllObjects];
[combinedArray addObjectsFromArray:[uniqueEvents allObjects]];
NSLog(#"combinedArray: %# ...", combinedArray);
}
Output:
combinedArray: (
"STEVE JOBS",
"TONY STARK",
"SANSA STARK",
"BILL GATES"
) ...
You can achieve the desired result with the following,
NSArray *arr1 = #[#"26", #"26", #"25", #"25", #"3", #"3", #"4", #"4"];
NSArray *arr2 = #[#"sticker", #"sticker", #"sticker", #"sticker", #"sticker", #"frame", #"frame", #"frame"];
NSDictionary *dict = [NSDictionary dictionaryWithObjects:arr2
forKeys:arr1];
NSArray *distinctArr1 = [[NSOrderedSet orderedSetWithArray:arr1] array];
NSMutableArray *distinctArr2 = [NSMutableArray array];
for (NSString *num1 in distinctArr1) {
[distinctArr2 addObject:dict[num1]];
}
// Your distinctArr2 is sorted based on distinctArr1's indices
Try this one.
NSArray *arrayOne = #[#"TONY", #"SANSA", #"BILL", #"BILL", #"STEVE", #"STEVE"];
NSArray *arrayTwo = #[#"STARK", #"STARK", #"GATES", #"GATES", #"JOBS", #"JOBS"];
NSArray *uniqueArrayOne = [[NSSet setWithArray:arrayOne] allObjects];
NSMutableArray *uniqueArrayTwo = [NSMutableArray array];
[uniqueArrayOne enumerateObjectsUsingBlock:^(id _Nonnull obj1, NSUInteger idx, BOOL * _Nonnull stop) {
NSUInteger found = [arrayOne indexOfObjectPassingTest:^BOOL(id _Nonnull obj2, NSUInteger idx, BOOL * _Nonnull stop) {
return [(NSString *)obj2 isEqualToString:(NSString *)obj1];
}];
[uniqueArrayTwo addObject:[arrayTwo objectAtIndex:found]];
}];
NSLog(#"%#, %#", uniqueArrayOne, uniqueArrayTwo);
I have an array like this:
NSArray *needSortedArray = #[#"Alex", #"Rachel", #"Mohamad"];
and an array of index like this:
NSArray *indexArray = #[#1, #0, #2];
So the output I want will look like this:
needSortedArray = #[#"Rachel", #"Alex", #"Mohamad"];
How can I do this? Is it possible?
Try this:
NSArray *unsortedArray = #[#"Alex", #"Rachel", #"Mohamad"];
NSArray *indexArray = #[#1, #0, #2];
NSMutableArray * sortedArray = [[NSMutableArray alloc] initWithCapacity:unsortedArray.count];
for (NSNumber * num in indexArray)
{
[sortedArray addObject:[unsortedArray objectAtIndex:num.integerValue]];
}
//now sortedArray has sorted objects.
Solution that supports any comparable types of indexes:
NSArray<NSString*> *unsortedArray = #[#"Alex", #"Rachel", #"Mohamad", #"Andrew"];
NSArray<NSNumber*> *indexArray = #[#1, #12, #23, #12];
NSParameterAssert([indexArray count] == [unsortedArray count]);
NSArray* sorted = [unsortedArray sortedArrayUsingComparator:^NSComparisonResult(id _Nonnull obj1, id _Nonnull obj2) {
NSNumber* index1 = indexArray[[unsortedArray indexOfObjectIdenticalTo:obj1]];
NSNumber* index2 = indexArray[[unsortedArray indexOfObjectIdenticalTo:obj2]];
NSComparisonResult result = [index1 compare:index2];
return result;
}];
NSLog(#"Sorted array: %#", sorted);
I have an array of values, and I'd like to sort it from highest to lowest values. Here's my array:
#[#0.985517248005697843460382, #0.000103821940243745174581, #0.002930049254083499140483, #0.006089428685598983863325, #0.000169959081717878927225 #0.038708805305937427077012, #0.005785644142951103588435, #0.003949420720490224266663 #0.003306789895982742942537, #0.005520713777168946394258];
What's the most efficient way to create a new array, but instead of containing the sorted values, it would contain the indexes from the original array?
Currently this is what I'm doing:
NSArray *array = #[#3, #5, #7, #2, #4, #4.1, #1, #10];
NSArray *sortedArray = [array sortedArrayUsingSelector: #selector(compare:)];
NSMutableArray *arraySortedByOriginalIndexes = [[NSMutableArray alloc] init];
for (int i = 0; i < sortedArray.count; i++) {
NSUInteger index = [array indexOfObject:sortedArray[i]];
[arraySortedByOriginalIndexes addObject:#(index)];
}
Here is the simple solution if no numbers in array are equal.
NSArray *sortedArray = [array sortedArrayUsingSelector: #selector(compare:)];
NSMutableArray *mutableIndexes = [NSMutableArray array];
for (NSNumber *number in sortedArray) {
[mutableIndexes addObject:#([array indexOfObject:number])];
}
NSArray *indexes = [mutableIndexes copy];
Again, it only works when no numbers are equal.
I have 3 NSMutableArrays of identical size. They are "linked" that means that for the corresponding index they have something related to each other.
tableData = [NSMutableArray arrayWithObjects:#"Egg Benedict", #"Mushroom Risotto", #"Full Breakfast", nil]
thumbnails = [NSMutableArray arrayWithObjects:#"egg_benedict.jpg", #"mushroom_risotto.jpg", #"full_breakfast.jpg",nil]
prepTime = [NSMutableArray arrayWithObjects:#"10min", #"15min", #"8min",nil]
This comes from a tutorial I'm playing on.
I'm filtering the tableData array like this:
NSPredicate *resultPredicate = [NSPredicate
predicateWithFormat:#"SELF contains[cd] %#",
searchText];
searchResultsData = [[tableData filteredArrayUsingPredicate:resultPredicate] mutableCopy];
where searchText is the string containing the filter (for example "egg").
This works great, I mean I have the correct filtering. (searchResultsData is another NSMutableArray)
What I need to do is filter the other two NSMutableArrays on the basis of the result got from the NSPredicate above.
So I created other two NSMutableArrays called "searchResultThumbnails" and "searchResultPrepTime".
I'm expecting this: if I filter using the word "egg" I want the first element containing "egg" from the "tableData" array (in this case only one element) and the correspondent element at index in the thumbnails and preptime arrays.
So after filtering with "Egg" the result should be:
searchResultData = "Egg"
searchResultThumbnails = "egg_benedict.jpg"
searchResultPrepTime = "10min"
Thank you for your help.
Believing "They are "linked" that means that for the corresponding index they have something related to each other." as your situation
NSPredicate *resultPredicate = [NSPredicate
predicateWithFormat:#"SELF contains[cd] %#",
searchText];
searchResultsData = [[tableData filteredArrayUsingPredicate:resultPredicate] mutableCopy];
NSString *searchedText = [searchResultsData objectAtIndex:0];
NSInteger index = [tableData indexOfObject:searchedText]; //if searchedText = "Egg"
NSString *thumb = [thumbnails objectAtIndex:index];
NSString *prep= [prepTime objectAtIndex:index];
But this is not a better way to do this.
You got couple of options like
You can use a custom Class which might have properties item, thumbnail, prepTime.
You can also use a Array of dictionaries similar to the following format,
array = (
{
searchResultData = "Egg"
searchResultThumbnails = "egg_benedict.jpg"
searchResultPrepTime = "10min"
}
{
searchResultData = "someItem"
searchResultThumbnails = "some.jpg"
searchResultPrepTime = "10min"
}
)
Try this:
NSArray* tableData = [NSMutableArray arrayWithObjects:#"Egg Benedict", #"Mushroom Risotto", #"Full Breakfast", nil];
NSArray* thumbnails = [NSMutableArray arrayWithObjects:#"egg_benedict.jpg", #"mushroom_risotto.jpg", #"full_breakfast.jpg",nil];
NSArray* prepTime = [NSMutableArray arrayWithObjects:#"10min", #"15min", #"8min",nil];
NSMutableArray *storedIndex = [NSMutableArray arrayWithCapacity:tableData.count];
for (NSUInteger i = 0 ; i != tableData.count ; i++) {
[storedIndex addObject:[NSNumber numberWithInteger:i]];
}
//Now you are going to sort tabledata.. with it we will sort storedIndexs
//suppose we will compare the strings for this time
[storedIndex sortUsingComparator:^NSComparisonResult(id obj1, id obj2){
NSString *lhs = [[tableData objectAtIndex:[obj1 intValue]] lowercaseString];
NSString *rhs = [[tableData objectAtIndex:[obj2 intValue]] lowercaseString];
return [lhs compare:rhs];
}]; //now storedIndex are sorted according to sorted tableData array
NSMutableArray *sortedTableData = [NSMutableArray arrayWithCapacity:tableData.count];
NSMutableArray *sortedThumbnail = [NSMutableArray arrayWithCapacity:tableData.count];
NSMutableArray *sortedPrepTime = [NSMutableArray arrayWithCapacity:tableData.count];
[p enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
NSUInteger pos = [obj intValue];
[sortedTableData addObject:[tableData objectAtIndex:pos]];
[sortedThumbnail addObject:[thumbnails objectAtIndex:pos]];
[sortedPrepTime addObject:[prepTime objectAtIndex:pos]];
}];
//Now all will be correct index relation to each other as previous
It will work perfectly.
Happy coding. :)
I have an NSMutableDictionary that maps NSString to NSString (although the values are NSStrings, they are really just integers).
For example consider the following mappings,
"dog" --> "4"
"cat" --> "3"
"turtle" --> "6"
I'd like to end up with the top 10 entries in the dictionary sorted by decreasing order of the value. Can someone show me code for this? Perhaps there is an array of keys and another array of values. However it is, I don't mind. I'm just trying to have it be efficient.
Thank you!
Get the Array of the Values, sort that array and then get the key corresponding to the value.
You can get the values with:
NSArray* values = [myDict allValues];
NSArray* sortedValues = [values sortedArrayUsingSelector:#selector(comparator)];
But, if the collection is as you show in your example, (I mean, you can infer the value from the key), you can always sort the keys instead messing with the values.
Using:
NSArray* sortedKeys = [myDict keysSortedByValueUsingSelector:#selector(comparator)];
The comparator is a message selector which is sent to the object you want to order.
If you want to order strings, then you should use a NSString comparator.
The NSString comparators are i.e.: caseInsensitiveCompare or localizedCaseInsensitiveCompare:.
If none of these are valid for you, you can call your own comparator function
[values sortedArrayUsingFunction:comparatorFunction context:nil]
Being comparatorFunction (from AppleDocumentation)
NSInteger intSort(id num1, id num2, void *context)
{
int v1 = [num1 intValue];
int v2 = [num2 intValue];
if (v1 < v2)
return NSOrderedAscending;
else if (v1 > v2)
return NSOrderedDescending;
else
return NSOrderedSame;
}
The simplest way is:
NSArray *sortedValues = [[yourDictionary allValues] sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)];
NSMutableDictionary *orderedDictionary=[[NSMutableDictionary alloc]init];
for(NSString *valor in sortedValues){
for(NSString *clave in [yourDictionary allKeys]){
if ([valor isEqualToString:[yourDictionary valueForKey:clave]]) {
[orderedDictionary setValue:valor forKey:clave];
}
}
}
Use this method:
- (NSArray *)sortKeysByIntValue:(NSDictionary *)dictionary {
NSArray *sortedKeys = [dictionary keysSortedByValueUsingComparator:^NSComparisonResult(id obj1, id obj2) {
int v1 = [obj1 intValue];
int v2 = [obj2 intValue];
if (v1 < v2)
return NSOrderedAscending;
else if (v1 > v2)
return NSOrderedDescending;
else
return NSOrderedSame;
}];
return sortedKeys;
}
Call it and then create a new dictionary with keys sorted by value:
NSDictionary *dictionary = [[NSDictionary alloc] initWithObjectsAndKeys:
#"4", #"dog",
#"3", #"cat",
#"6", #"turtle",
nil];
NSArray *sortedKeys = [self sortKeysByIntValue:dictionary];
NSMutableDictionary *sortedDictionary = [[NSMutableDictionary alloc] init];
for (NSString *key in sortedKeys){
[sortedDictionary setObject:dictionary[key] forKey:key];
}
Sorting the keys and using that to populate an array with the values:
NSArray *keys = [dict allKeys];
NSArray *sKeys = [keys sortedArrayUsingSelector:#selector(caseInsensitiveCompare:)];
NSMutableArray *sValues = [[[NSMutableArray alloc] init] autorelease];
for(id k in sKeys) {
id val = [dict objectForKey:k];
[sValues addObject:val];
}
NSSortDescriptor *descriptor = [[NSSortDescriptor alloc] initWithKey:#"interest" ascending:YES];
[unsortedArray sortUsingDescriptors:[NSArray arrayWithObjects:descriptor,nil]];
recentSortedArray = [stories copy];
if you want to sort data in ascending order for key 'name' for such kind of Example then this may help you.
arrayAnimalList = [
{
'name' = Dog,
'animal_id' = 001
},
{
'name' = Rat,
'animal_id' = 002
},
{
'name' = Cat,
'animal_id' = 003
}
];
This is a code which help you to get sorted array
//here you have to pass key for which you want to sort data
NSSortDescriptor *descriptor = [[NSSortDescriptor alloc] initWithKey:#"name" ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObject:descriptor];
// here you will get sorted array in 'sortedArray'
NSMutableArray * sortedArray = [[arrayAnimalList sortedArrayUsingDescriptors:sortDescriptors] mutableCopy];