-1
- (NSMutableArray *)sortMethod:(NSArray *)array SortingKey:(NSString *)key Ascending:(BOOL)ascending CaseInsensitiveCompare:(BOOL)caseInCompare
{
    if(key && key.length > 0)
    {
        NSSortDescriptor *sortDescriptor = nil;
        if(caseInCompare)
            sortDescriptor = [[NSSortDescriptor alloc] initWithKey:key ascending:ascending selector:@selector(localizedCaseInsensitiveCompare:)];
        else
            sortDescriptor = [[NSSortDescriptor alloc] initWithKey:key ascending:ascending];
        NSArray *sortedArray = [array sortedArrayUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]];
        return [NSMutableArray arrayWithArray:sortedArray];
    }
    
    return nil;
}

my app is doing case-insensitive search for English language. but its not searching for only one Bulgarian character and that is "д". when we type "Д" in capital, it gives all the searches, but when we type that "д" in small, it is not giving any search results. please give me a solution on this. Thanks a lot.

SonalB
  • 13
  • 4

1 Answers1

0

As per the doc when we use custom selector then the objects which are compared against each other should implement the custom selector method and logic to return the result.

You construct instances of NSSortDescriptor by specifying the key path of the property to compare and the order of the sort (ascending or descending). 
Optionally, you can also specify a selector to use to perform the comparison, which allows you to specify other comparison selectors, such as localizedStandardCompare: and localizedCaseInsensitiveCompare:. Sorting **raises an exception** if the objects don’t respond to the sort descriptor’s comparison selector.

As explained above we need to implement the sort descriptor’s comparison selector in TaggedDate

Update:

NSSortDescriptor can also be used with comparator instead of expecting the objects to implement the selector.

NSArray* wordsOfVaryingLength =  @[@"crow",@"eagle",@"goose"];
  
  NSComparisonResult (^stringLengthCompare)(NSString*, NSString*) = ^NSComparisonResult(NSString *stringOne, NSString *stringTwo) {
      NSComparisonResult lengthCompare = NSOrderedSame;
      if (stringOne.length < stringTwo.length)
          lengthCompare = NSOrderedAscending;
      if (stringOne.length > stringTwo.length)
          lengthCompare = NSOrderedDescending;
      return lengthCompare;
  };
  
  NSSortDescriptor *sortByLengthAsc = [NSSortDescriptor sortDescriptorWithKey:nil ascending:YES comparator:stringLengthCompare];
  NSLog(@"From shortest word to longest: %@", [wordsOfVaryingLength sortedArrayUsingDescriptors:@[sortByLengthAsc]]);
  NSSortDescriptor *sortByLengthDesc = [NSSortDescriptor sortDescriptorWithKey:nil ascending:NO comparator:stringLengthCompare];
  NSLog(@"From longest word to shortest: %@", [wordsOfVaryingLength sortedArrayUsingDescriptors:@[sortByLengthDesc]]);

Here stringLengthCompare will have the comparison logic, similarly for the case sensitive or insensitive use case we need to put that logic here, taken from

let descriptor = NSSortDescriptor(key: "title", ascending: true) { (string1, string2) -> ComparisonResult in
        guard let s1 = string1 as? String, let s2 = string2 as? String else {
            return ComparisonResult.orderedSame
        }
        if s1.lowercased() < s2.lowercased() {
            return ComparisonResult.orderedAscending
        } else if s1.lowercased() == s2.lowercased() {
            return ComparisonResult.orderedSame
        } else {
            return ComparisonResult.orderedDescending
        }
    } 
vignesh
  • 994
  • 10
  • 12
  • `TaggedDate` that's usually an inner Apple class for `NSDate`. So you wouldn't need in fact a case insensitive, it's a date, not a string. – Larme Feb 14 '23 at 10:31
  • I thought its a custom class of which objects are created and stored in an array. Which is then used for sorting with `NSSortDescriptor`. agree that it doesn't require case insensitivity for the date comparison thanks for pointing out. – vignesh Feb 14 '23 at 10:47
  • but I want to just apply case insensitive search for the array. I tried applying filter on array but it didn't work – SonalB Feb 14 '23 at 12:06
  • @SonalB And what does it mean to perform a case insensitive search on an array of NSDate objects? – HangarRash Feb 14 '23 at 23:30
  • I honestly dont know why such error is coming, but I know that we are passing string array to this method for parameter "data". I want that array to be search using case-sensitive way. – SonalB Feb 15 '23 at 05:43
  • please give me a solution so no need to apply above method. I can directly search using case-sensitive way on sting array.. Thanks – SonalB Feb 15 '23 at 05:43
  • @SonalB If it is about sorting the string then this question is already asked [here](https://stackoverflow.com/questions/11114567/nsmutablearray-sorting-case-insensitive) – vignesh Feb 15 '23 at 06:30
  • I applied ur solution and ran project @vignesh, still getting same error - Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSTaggedDate caseInsensitiveCompare:]: unrecognized selector sent to instance 0xe1c43ea974ba4739' – SonalB Feb 15 '23 at 06:47
  • I updated code by replacing if conditon's sortDescriptor init method with following code - if(ciCompare) { printf("if sortdata"); sortDescriptor = [[NSSortDescriptor alloc]initWithKey:key ascending:ascending]; NSArray *resa = [data sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)]; return [NSMutableArray arrayWithArray:resa]; } but still did not work. now following error is coming - [MediaTitles caseInsensitiveCompare:] - here, mediaTitles is data array which of class MediaTitles which is having strings – SonalB Feb 15 '23 at 07:55
  • please help someone, I think we are near to finding solution as error is coming for string array, not for taagedate – SonalB Feb 15 '23 at 07:57
  • @vignesh sir, I checked with Bulgarian and English keyboard for case insensitive , it is working fine for English keyboard, but not working for Bulgarian only one letter "д".. what can be the solution? please tell me . thanks – SonalB Feb 15 '23 at 10:43
  • please @vignesh sir, give me a solution. thanks – SonalB Feb 15 '23 at 12:35
  • 2
    As I asked before, what is `data`? What objects is it holding? Edit your question with that iinformation. Also, what is supposed to be "д"? Is it a different letter? What's is case sensitive equivalent, as we might no all know Bulgarian language. Define not working, give a sample on where it should works. – Larme Feb 15 '23 at 14:04
  • @SonalB based on your comment I guess that the `sortMethod` is taking the array with different data types as input in that case you need mention more details in the question about Data type details etc. I have updated the ans to use comparator please try if it is working and also accept and vote for the comment and ans if it if working for you. – vignesh Feb 16 '23 at 06:51
  • thans for the solution @vignesh sir, I applied it and tried using English language , its working fine. but when try using Bulgarian word "д", its not giving results.please suggest some solutions. Its working for other Bulgarian characters, but only for this - "д ". Thanks – SonalB Feb 16 '23 at 13:10