简体   繁体   中英

Sort array with a count value

I have an array which contains some strings. For each character of a string an integer value is assigned. For example a=2,b=5,c=6 ,o=1,k=3 etc

The final value in the a string is the sum of the character's value. So that for an example string "BOOK" the string will be stored as "BOOK (7)". Similarly every string will have a final integer value. I would like to sort these array with these final integer values stored in the string which is present in each array index. The array contains more than 200,000 words. So the sorting process should be pretty fast. Is there any method for it?

A brutal quick example could be, if your strings structure is always the same, like "Book (7)" you can operate on the string by finding the number between the "()" and then you can use a dictionary to store temporally the objects:

    NSMutableArray *arr=[NSMutableArray arrayWithObjects:@"Book (99)",@"Pencil (66)",@"Trash (04)", nil];
    NSLog(@"%@",arr);

    NSMutableDictionary *dict=[NSMutableDictionary dictionary];
    //Find the numbers and store each element in the dictionary 
    for (int i =0;i<arr.count;i++) {
        NSString *s=[arr objectAtIndex:i];
        int start=[s rangeOfString:@"("].location;
        NSString *sub1=[s substringFromIndex:start];
        NSString *temp1=[sub1 stringByReplacingOccurrencesOfString:@"(" withString:@""];
        NSString *newIndex=[temp1 stringByReplacingOccurrencesOfString:@")" withString:@""];
        //NSLog(@"%d",[newIndex intValue]);
        [dict setValue:s forKey:newIndex];
    }
    //Sorting the keys and create the new array
    NSArray *sortedValues = [[dict allKeys] sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];
    NSMutableArray *newArray=[[NSMutableArray alloc]init];
    for(NSString *valor in sortedValues){
               [newArray addObject:[dict valueForKey:valor]];
        }
    NSLog(@"%@",newArray);

This prints:

(
"Book (99)",
"Pencil (66)",
"Trash (04)"
)

(
"Trash (04)",
"Pencil (66)",
"Book (99)"
)

as i understand, you want to sort an array which contains string formated in the following

a=3

and you want to sort according to the number while ignoring the character. in this case the following code will work with you

-(NSArray *)Sort:(NSArray*)myArray
{
    return [myArray sortedArrayUsingComparator:(NSComparator)^(id obj1, id obj2)
            {
                NSString *first = [[obj1 componentsSeparatedByString:@"="] objectAtIndex:1];
                NSString *second = [[obj2 componentsSeparatedByString:@"="] objectAtIndex:1];
                return [first caseInsensitiveCompare:second];
            }];
}

How to use it:

NSArray *arr= [[NSArray alloc] initWithObjects:@"a=3",@"b=1",@"c=4",@"f=2", nil];
NSArray *sorted = [self Sort:arr];

for (NSString* str in sorted)
{
    NSLog(@"%@",str);
}

Output

b=1
f=2
a=3
c=4

Try this methods

+(NSString*)strTotalCount:(NSString*)str
{
   NSInteger totalCount =  0;
   // initial your character-count directory
   NSDictionary* characterDictionary = [NSDictionary dictionaryWithObjectsAndKeys:
    [NSNumber numberWithInt:2], [NSString stringWithUTF8String:"a"],
    [NSNumber numberWithInt:5], [NSString stringWithUTF8String:"b"],
    [NSNumber numberWithInt:6], [NSString stringWithUTF8String:"c"],
    [NSNumber numberWithInt:1], [NSString stringWithUTF8String:"o"],
    [NSNumber numberWithInt:3], [NSString stringWithUTF8String:"k"],
                                   nil];

   NSString* tempString = str;
  for (NSInteger i =0; i<tempString.length; i++) {
    NSString* character  = [tempString substringWithRange:NSMakeRange(i, 1)];
    character = [character lowercaseString];
    NSNumber* count = [characterDictionary objectForKey:character];
    totalCount += [count integerValue];
  };
  return [NSString stringWithFormat:@"%@(%d)",str,totalCount];
}

The test sentence:

 NSLog(@"%@", [ViewController strTotalCount:@"BOOK"]);

will output " BOOK(10) "

You may change the ViewController to you own class name;

First - create a custom object to save your values. Don't put the value inside the string. Sorting is not your base problem. The problem is that you are saving values into a string from where they are difficult to extract.

@interface StringWithValue

@property (nonatomic, copy, readwrite) NSString* text;
@property (nonatomic, assign, readwrite) NSUInteger value;

- (id)initWithText:(NSString*)text;

- (NSComparisonResult)compare:(StringWithValue*)anotherString;

@end

@implementation StringWithValue

@synthesize text = _text;
@synthesize value = _value;

- (id)initWithText:(NSString*)text {
    self = [super init];

    if (!self) {
       return nil;
    }

    self.text = text;
    self.value = [self calculateValueForText:text];

    return self;
}

- (NSComparisonResult)compare:(StringWithValue*)anotherString {
   if (self.value  anotherString.value) {
      return NSOrderedDescending;
   }
   else {
      return NSOrderedSame;
   }
}

- (NSString*)description {
    return [NSString stringWithFormat:@"%@ (%u)", self.text, self.value];
}

@end

Sorting the array then would be a simple use of sortUsingSelector: . Note this will beat all other answers in performance as there is no need to parse the value with every comparison.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM