I have an NSString that returns a list of values like this:
test_1=value_1
test/2=value_2
test3=value_3 value_4
test_4=value_5/value_6
...
More realistic result values:
inameX=vlan2
hname=server
lanipaddr=192.168.1.1
lannetmask=255.255.255.0
islan=0
islwan=0
dhcplease=604800
dhcplease_1=302400
ct_tcp_timeout=0 1200 40 30 60 60 5 30 15 0
ct_timeout=10 10
ct_udp_timeout=25 60
ctf_disable=1
ddnsx0=
cifs2=0<\\192.168.1.5
and so on...
If I do:
for (id key in dict) {
NSLog(#"key: %#, value: %#", [dict objectForKey:key], key);
}
it outputs:
key: inameX, value: vlan2
key: hname value: server
key: lanipaddr value: 192.168.1.1
key: lannetmask value: 255.255.255.0
This list is stored in one NSString *result. Not sure if I should put it in an array for this but I need to be able to call a function or command that will return a specific value_X based on the argument to match the variable. For example, get value of test_1 variable then it would return value_1. Or get test_4 then it would return value_5/value_6
Any idea how I can do that?
I appreciate your help. Thanks!
You probably want the method in NSString called componentsSeparatedByCharactersInSet: to split up that one string into an array. Since your values are separated by '=' and new line characters ('\n'), you want the set to include those two characters:
NSArray *strings = [NSString componentsSeparatedByCharactersInSet:
[NSCharacterSet characterSetWithCharactersInString:#"=\n"]];
And then you can make this into a dictionary with NSDictoinary's dictionaryWithObjects: AndKeys: But first, you need to split that array into two arrays; one with objects, one with keys:
NSMutableArray *keys = [NSMutableArray new];
NSMutableArray *values = [NSMutableArray new];
for (int i = 0; i < strings.count; i++) {
if (i % 2 == 0) { // if i is even
[keys addObject:strings[i]];
}
else {
[values addObject:strings[i]];
}
}
Then you put them into an NSDictonary
NSDictionary *dict = [NSDictionary dictionaryWithObjects:values forKeys:keys];
NSLog(#"%#", dict[#"test_1"]) // This should print out 'value_1'
Hope that helps!
Use an NSDicationary. NSDictionaries are key value stores. In other words, there are a list of keys. Each key is unique. Each key has an associated value. The value can be any data type and the key has to conform to the NSCopying protocol (typically an NSString). If you try to access the value for a key that doesn't exist in your NSDictionary, the return value will be nil.
//create the dictionary and populate it
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
[dict setObject:#"value_1" forKey:#"key_1"];
[dict setObject:#"value_2" forKey:#"key_2"];
[dict setObject:#"value_3" forKey:#"key_3"];
[dict setObject:#"value_4" forKey:#"key_4"];
NSString *stringInput = [self getStringInput];//however you find out your input
//find your string value based on the key passed in
NSString *strValue = [dict objectForKey:stringInput];
You can use a NSScanner to make this work.
Scan for the string for which you want the value, and then scan the string until you encounter \n and then use it for your requirement.
NSScanner *scan =[NSScanner scannerWithString:theString];
[scan scanString:keyString inToString:nil];
[scan setScanLocation:[scan scanLocation]+1];
[scan scanString:#"\n" inToString:requiredString];
So requiredString is the string which you want.
Related
I have a code in which the existing handle dates in an array, separates the day of the month and will put inside a NSMutableDictionary with their respective day of the month, the array has the following structure:
"12/01/2014" //Structure of my date is -> dd-mm-yyyy
"16/01/2014"
"30/01/2014"
"02/02/2014"
"08/02/2014"
I use this code to put this values inside a NSMutableDictionary:
dictionary = [NSMutableDictionary dictionary];
for(int x=0;x<[list count];x++){
NSMutableArray *lstaInfo2 = [[list[x] componentsSeparatedByString:#"/"] mutableCopy];
if([lstaInfo2[1] isEqual: #"01"]){
[dictionary setValue:list[x] forKey:[NSString stringWithFormat:#"January of %#",lstaInfo2[2]]];
}
if([lstaInfo2[1] isEqual: #"02"]){
[dictionary setValue:list[x] forKey:[NSString stringWithFormat:#"February of %#",lstaInfo2[2]]];
}
}
The values that I hoped to return within the variable dictionary is:
January of 2014 =>
"12/01/2014"
"16/01/2014"
"30/01/2014"
February of 2014 =>
"02/02/2014"
"08/02/2014"
But the variable dictionary, returns only the last values, like this:
January of 2014 =>
"30/01/2014"
February of 2014 =>
"08/02/2014"
why? How can I solve this problem?
dictionary = [NSMutableDictionary dictionary];
for(int x=0;x<[list count];x++){
NSString* key = [self getKeyForDate:list[x]];
NSMutableArray* listForMonth = dictionary[key];
if (key == nil) {
listForMonth = [NSMutableArray array];
[dictionary setValue:listForMonth forKey:key];
}
[listForMonth addObject:list[x]];
}
.....
In init
monthArray = #[#"January", #"February", #"March" ...
Separate method:
-(NSString*) getKeyForDate:(NSString*)date {
NSMutableArray *lstaInfo2 = [date componentsSeparatedByString:#"/"] mutableCopy];
NSInteger monthNum = lstaInfo2[0].integerValue;
NSString* result = [NSString stringWithFormat;#"%# of %#", monthArray[monthNum-1], lstaInfo2[2]];
return result;
}
You can also use NSDateFormatter to parse the date, and NSCalendar to serve up the month names, but that's getting too deep for one lesson.
When you try to add new value to the dictionary check whether value for this key is actually in the dictionary. If no, create and set NSMutableArray object for this key and add values to this array.
Try this:
```objc
dictionary = [NSMutableDictionary dictionary];
for(int x=0; x < [list count]; x++){
NSArray *lstaInfo2 = [list[x] componentsSeparatedByString:#"/"];
NSString *key;
if([lstaInfo2[1] isEqual: #"01"]){
key = [NSString stringWithFormat:#"January of %#",lstaInfo2[2]];
}
if([lstaInfo2[1] isEqual: #"02"]){
key = [NSString stringWithFormat:#"February of %#",lstaInfo2[2]];
}
if (key) {
//if there is no value for the specified key create and set
//NSMutableArray object for this key, otherwise keep value for
//the key without modyfing it.
dictionary[key] = dictionary[key] ?: [NSMutableArray array];
[dictionary[key] addObject:list[x]];
}
}
```
It is because setValue:forKey: doesn't append to the current value. So in the first iteration through the loop you set "January of 2014" => ["12", "01", "2014"] and in the next iteration you set "January of 2014" => ["16", "01", "2014"], and so on. You want to map from a string to a NSMutableArray.
I would really suggest you use the NSDateFormatter class for this: https://developer.apple.com/library/ios/documentation/cocoa/reference/foundation/classes/nsdateformatter_class/Reference/Reference.html#//apple_ref/occ/instm/NSDateFormatter/. It will be easier and much more flexible than manually parsing the dates.
I have a dictionary declared, like this,
NSString *responseString = [request responseString];
responseDict = [responseString JSONValue];
for (id key in responseDict){
NSLog(#"%# : %#", key, [responseDict objectForKey:key]);
}
Result :
013-01-22 00:14:02.323 PromoTest[2352:c07] A : 0
2013-01-22 00:14:02.325 PromoTest[2352:c07] B : 1
2013-01-22 00:14:02.325 PromoTest[2352:c07] C : 0
now, I want to compare the value and do some operation on it. I presumed the value for a key is of type NSString and compared it to my constant NSString, like this,
NSString *myString1 = #"0";
NSString *myString2 = [responseDict objectForKey:#"A"];
NSLog(#"%d", (myString1 == myString2)); //1
NSLog(#"%d", [myString1 isEqualToString:myString2]); //1
Result:
2013-01-22 00:19:12.966 PromoTest[2423:c07] 0
2013-01-22 00:19:12.966 PromoTest[2423:c07] 0
Where am i going wrong?? Is my comparison wrong? How do I go about correctly comparing the content??
The data is being received as response data from a web service. I am just converting the data into a dictionary for easily using it. The web service returns a JSON object,
{"A":0,"B":1,"C":0}
NSDictionary method isEqualToDictionary can be used to compare 2 dictionaries
Returns a Boolean value that indicates whether the contents of the
receiving dictionary are equal to the contents of another given
dictionary.
For example:
[myDictionary isEqualToDictionary:expectedDictionary]
The only reasonable explanation is that [responseDict objectForKey:#"A"] is not returning a NSString.
You are probably getting a NSNumber back, therefore the comparison fails.
If that's the case you need to get a NSString from the NSNumber before comparing it against your constant. You can do it by
NSString * myString2 = [[responseDict objectForKey:#"A"] stringValue];
Also never use == to compare NSStrings instances. Stick with isEqualToString and you'll be good.
Instead of comparing strings you could also compare number object. here including with a check, if the returned object is a NSNumber, if not, try as string:
if([responseDict[#"A"] isKindOfClass:[NSNumber class]]){
NSNumber *myNumber1 = #0;
NSNumber *myNumber2 = [responseDict objectForKey:#"A"];
NSLog("Same number: %#",[myNumber1 isEqualToNumber:myNumber2] ? #"YES" : #"NO");
} else if([responseDict[#"A"] isKindOfClass:[NSString class]]){
NSString *myString1 = #"0";
NSString *myString2 = [responseDict objectForKey:#"A"];
NSLog("Same string: %#",[myString1 isEqualToString:myString2] ? #"YES" : #"NO");
}
I've got a NSDictionary and I'd like put all of it's objects and keys into a NSString, so that I can finally display them in a label like this:
key1: object1
key2: object2
key3: object3
... ...
Any ideas?
Build the string and then set it to the labels text.
NSMutableString *myString = [[NSMutableString alloc] init];
[dictionary enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
[myString appendFormat:#"%# : %#\n", key, obj];
}];
self.label.text = myString;
Note
The docs (String Programming Guide) for the %# format specifier state:
%#
Objective-C object, printed as the string returned by descriptionWithLocale: if available, or description otherwise. Also works with CFTypeRef objects, returning the result of the CFCopyDescription function.
So if these are your own custom objects in the dictionary you will most likely need to override the description method to provide more meaningful output
Update
You mention that you need your output sorted by keys - dictionaries are not ordered so you will have to do it differently - this example assumes that your keys are strings
NSArray *sortedKeys = [[dictionary allKeys] sortedArrayUsingSelector:#selector(caseInsensitiveCompare:)];
NSMutableString *myString = [[NSMutableString alloc] init];
for (NSString *key in sortedKeys) {
[myString appendFormat:#"%# : %#\n", key, [dictionary objectForKey:key]];
}
self.label.text = myString;
try this
for(id key in [dictionary allKeys])
{
id value = [dictionary objectForKey:key];
NSLog(#"%# : %#", key, value);
}
NSString *row;
for (id key in dictionary) {
row = [NSString stringWithFormat:"%#: %#", key, [dictionary objectForKey:key]];
// do something with your row string
}
Iam trying to append two time values from my TCTime object and display in label, even though I added "\n" towards the end it is printing only the first value but not the second value.
_feedTimes is NSArray.
NSMutableString *myString = [[NSMutableString alloc] init];
TCTime *time = _feedTimes[indexPath.row];
[myString appendFormat:#"%s : %#\n", "Time 1 ", time.Time1];
[myString appendFormat:#"%s : %#\n", "Time 2 ", time.Time2];
self.label.text = myString;
I know to read the contents of file in Objective-C, but how to take it as the input to hashtable.
Consider the contents of text file as test.txt
LENOVA
HCL
WIPRO
DELL
Now i need to read this into my Hashtable as Key value pairs
KEY VAlue
1 LENOVA
2 HCL
3 WIPRO
4 DELL
You want to parse your file into an array of strings and assign each element in this array with a key. This may help you get in the right direction.
NSString *wholeFile = [NSString stringWithContentsOfFile:#"filename.txt"];
NSArray *lines = [wholeFile componentsSeparatedByString:#"\n"];
NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithCapacity:[lines count]];
int counter = 1;
for (NSString *line in lines)
{
if ([line length])
{
[dict setObject:line forKey:[NSString stringWithFormat:"%d", counter]];
// If you want `NSNumber` as keys, use this line instead:
// [dict setObject:line forKey:[NSNumber numberWithInt:counter]];
counter++;
}
}
Keep in mind this isn't the most efficient method of parsing your file. It also uses the deprecated method stringWithContentsOfFile:.
To get the line back, use:
NSString *myLine = [dict objectForKey:#"1"];
// If you used `NSNumber` class for keys, use:
// NSString *myLine = [dict objectForKey:[NSNumber numberWithInt:1]];
I was wondering if someone can show me how to sort an NSDictionary; I want to read it starting from the last entry, since the key is Date + Time and I want to be able to append it to an NSMutableString. I was able to read it using an enumerator but I don't get the results I want.
Thanks
For your requirements the easiest way is to create a new array from the keys, sort that, then use the array to reference items from the original dictionary.
(Note myComparison is your own method that will compare two keys).
NSMutableArray* tempArray = [NSMutableArray arrayWithArray:[myDict allKeys]];
[tempArray sortedArrayUsingSelector:#selector(myComparison:)];
for (Foo* f in tempArray)
{
Value* val = [myDict objectForKey:f];
}
I've aggregated some of the other suggestions on StackOverflow on sorting an NSDictionary into something very compact that will sort alphabetically. I have a Plist file in 'path' that I load in to memory and want to dump.
NSDictionary *glossary = [NSDictionary dictionaryWithContentsOfFile: path];
NSArray *array1 = [[glossary allKeys] sortedArrayUsingDescriptors:#[ [NSSortDescriptor sortDescriptorWithKey:#"" ascending:YES selector:#selector(localizedStandardCompare:)] ]];
for ( int i=0; i<array1.count; i++)
{
NSString* key = [array1 objectAtIndex:i];
NSString* value = [glossary objectForKey:key];
NSLog(#"Key=%#, Value=%#", key, value );
}