iOS - key index from 3 strings - ios

I am storing items in a large NSMutableArray. 3 strings define a unique item in this array. I'd like to have a NSMutableDictionary which maps the 3 string key to an entry in the array.
In my code the first 3 objects in item are the 3 strings which define a unique item. How can I most efficiently create the key to do the lookup? I'm guessing stringWithFormat isn't the best idea. I'm trying to speed up a large amount of lookups that occur.
- (void)addItem:(NSArray*)item {
// create entry from item
[mEntries addObject:entry];
NSString *key = [NSString stringWithFormat:#"%#%#%#", [item objectAtIndex:0],
[item objectAtIndex:1],[item objectAtIndex:2]];
[mEntryMap setObject:entry forKey:key];
}
- (Entry*)getItem:(NSArray*)strs {
NSString *key = [NSString stringWithFormat:#"%#%#%#", [strs objectAtIndex:0],
[strs objectAtIndex:1],[strs objectAtIndex:2]];
return [mEntryMap objectForKey:key];
}

Create string directly from array no need to use long method
- (void)addItem:(NSArray*)item {
// create entry from item
[mEntries addObject:entry];
NSString *key=[item componentsJoinedByString:#""];
[mEntryMap setObject:entry forKey:key];
}
- (Entry*)getItem:(NSArray*)strs {
NSString *key=[strs componentsJoinedByString:#""];
return [mEntryMap objectForKey:key];
}

Related

Order Date Strings in an Array

I have generated an Array of strings, each is a date from a NSDictionary (parsed from a plist file), the issue is that when creating the Array the NSDictionary has the years in a random order.
my code:
NSString *path = [[NSBundle mainBundle] pathForResource:_country ofType:#"plist"];
NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:path];
tableData = [[NSMutableArray alloc] init];
for (id key in dict) {
for (NSString *date in [dict objectForKey:key]){
NSString *baseString = #"";
baseString = [baseString stringByAppendingFormat:#"%# %#", date, key];
[tableData addObject:baseString];
}
}
So the above outputs strings like: December 05 2014
What I need is to find a way to then order this array so that the oldest date is first.
The NSArray class has a -sortedArrayUsingComparator: method that you can use to sort it. See the reference here.
You need to provide a suitable comparator as a block, according to the date format you are using. Probably using NSScanner or NSDateFormatter...
NSArray *sortedArray = [tableData sortedArrayUsingComparator: ^(NSString *str1, NSString *str2) {
if (/* str1 goes before str2 */) {
return NSOrderedDescending;
}
else if (/* str1 goes after str2 */) {
return NSOrderedAscending;
}
else {
return NSOrderedSame;
}
}];

Remove Duplicated Words From NSString and Save as New NSString

I have scenarios in which I may have an NSString that contains several words, some of them duplicated. What I want to do is take a string that looks like:
One Two Three Three Three Two Two Two One One Two Three
and make it look like:
One Two Three
There may be times that the exact length of the original NSString is different as well. What I have so far is:
NSString *hereitis = #"First Second Third Second Third First First First";
NSArray *words = [hereitis componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
NSCountedSet *countedSet = [NSCountedSet setWithArray:words];
NSMutableArray *finalArray = [NSMutableArray arrayWithCapacity:[words count]];
for(id obj in countedSet) {
if([countedSet countForObject:obj] == 1) {
[finalArray addObject:obj];
}
}
NSString *string = [finalArray componentsJoinedByString:#" "];
NSLog(#"String%#", string);
This however, just returns String in my array, and not ANY of the words.
This can actually be done way less painlessly. NSSet doesn't allow duplicate entries. So, you can break the string into an array, and use that array to create the set. From there, all you have to do is convert back, and the dupes will be removed.
NSString *inputString = #"One Two Three Three Three Two Two Two One One Two Three";
NSSet *aSet = [NSSet setWithArray:[inputString componentsSeparatedByString:#" "]];
NSString *outputString = [aSet.allObjects componentsJoinedByString:#" "];
NSLog(#"___%#___",outputString); // Outputs "___One Two Three___"
You will get an array of strings then
for(id obj in countedSet) {
if([countedSet countForObject:obj] == 1) {
[finalArray addObject:obj];
}
}
After that you can use your words
NSLog(#"%#", finalArray[0]); //log 'One'
You can use KVC Collection Operators for this as well:
NSString *string = #"One Two Three Three Three Two Two Two One One Two Three";
NSArray *items = [string componentsSeparatedByString:#" "];
NSArray *uniqueItems = [items valueForKeyPath:#"#distinctUnionOfObjects.self"];

select indexOfObject from NSArray in Xcode by comparing string

Hi I have NSarray values in Xcode. I need to get array indexOfObject by comparing string values.
my array values are
(
{
firstName = lord;
lastname = krishna;
},
{
firstName = priya;
lastname = amirtha;
}
)
If I type first name in textfield and click button means last name want to display in another textfield.
thank you.
To answer the title of your question:
NSString *compareString = #"something";
NSMutableArray *indexesOfMatches = [[NSMutableArray alloc]init];
for (NSString *string in theArray) {
if ([string isEqualToString:compareString]) {
NSNumber *index = [[NSNumber numberWithInterger:[theArray indexOfObject:string]];
[indexOfMatches addObject:index];
}
}
//indexOfMatches will now contain NSNumber objects that represent the indexes of each of the matching string objects in the array
I think that using an NSDictionary would be better for you though. Then you can simply keep the first and last names as Key Value pairs.
NSDictionary *names = #{#"lord" : #"krishna", #"priya" : #"amirtha" };
Then you can just do value for key when you get the first name:
NSString *firstName = #"lord";
NSString *lastName = [names valueForKey:firstName];
Store firstNameArray and lastNameArray a mutable array NSMutableArray.
Using Fast Enumeration. Suppose array is the array you are provided with
for (NSDictionary *item in array) {
[firstNameArray addObject:[item objectForKey:#"firstName"]];
[lastNameArray addObject:[item objectForKey:#"lastName"]];
}
After entering the data in firstNameTextField click the button
Button action method implementation
-(IBAction)btnClicked:(id)sender {
NSInteger index = [firstName indexOfObject:[firstNameTextField text]];
[lastNameTextField setText:[lastName objectAtIndex:index]];
}

Table Views with plists

I have a plist with the structure:
Root - Dictionary
Notes - Array
Item 0 - Dictionary
Title - String
Text - String
Date - String
I am then doing:
...
NSString *noteTitle;
NSString *noteText;
NSString *noteDate;
self.notes = [self.data objectForKey:#"Notes"];
And configure the cell like this:
cell.textLabel.text = [[self.notes objectAtIndex:indexPath.row] objectForKey:#"Title"];
cell.detailTextLabel.text = [[self.notes objectAtIndex:indexPath.row] objectForKey:#"Date"];
How do I then, in a button, add the noteTitle to the "Title" value in the plist?
[self.notes addObject:noteTitle];
When the alert is shown you need to know the index of the table you're editing so you know what index to edit when the button is tapped (row below). Then, you'll be doing something like:
[[self.notes objectAtIndex:row] setObject:noteTitle forKey:#"Title"];
If you really want to add a whole new item then you should be creating a new mutable dictionary, adding noteTitle to it and then adding that dictionary to self.notes (in which case you don't need the row).
NSDictionary *d = [[NSDictionary alloc] initWithObjectsAndKeys:noteTitle, #"Title",noteText, #"Text",noteDate, #"Date", nil];
[self.notes addObject:d];
if you want to fold 2 strings:
NSString *newString=[NSString stringWithFormat:#"%#%#",oneString,secondString];

Accessing NSMutableDictionary inside NSMutableArray

I have an NSMutableArray of NSMutableDictionary (it's a plist). Each dictionary in the array has 2 keys: 'id' and 'lu'.
How can I find the index in NSMutableArray of NSMutableDictionary where, for example, id = '47653'?
I tried to do it but it's not working:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
NSString *path = [basePath stringByAppendingPathComponent:#"id.plist"];
NSMutableArray *mut_array = [[NSArray arrayWithContentsOfFile:path] mutableCopy];
NSMutableDictionary *mut_dico = [[NSMutableDictionary alloc] init];
NSString *egalIDPlistData = [contentDictio objectForKey:#"id"];
for(mut_dico in mut_array) {
if([[mut_dico objectForKey:#"id"] isEqualToString:#"47653"]) {
NSLog(#"Test");
}
}
NSMutableArray *mut_array = [[NSArray arrayWithContentsOfFile:path] mutableCopy]; will create a mutable array of immutable dictionaries, not mutable dictionaries. mutableCopy is not a deep copy.
Regardless of mutability, the following will do what you want:
NSUInteger indexOfDictionary = [[array valueForKey:#"id"] indexOfObject:#"49711"];
if(indexOfDictionary == NSNotFound)
{
NSLog(#"no matching objects found!");
return;
}
NSDictionary *fullDictionary = [array objectAtIndex:indexOfObject];
The valueForKey: uses the fact that a key-value coding call on an array returns an array of the results of that call on each object in the array, in the same order, and the fact that NSDictionary will respond similarly in this situation to both valueForKey: and objectForKey:
As for the issue of whether what you're really dealing with is strings or numbers, try using just #49711 in place of #"49711" and if that works instead you've got numbers.
In your log id is 49711 & in your if condition it is 47653. Your condition will not satisfy until there is dictionary in your array with id = 47653
The objects in the loaded plist are not mutable.
Try:
for(NSDictionary * dict in mut_array)
{
if([[dict objectForKey:#"id"] isEqualToString:#"49711"]) {
NSLog(#"Test");
}
}

Resources