I'm sure there is a way to do this using blocks, but I cant figure it out. I want to to turn an NSDictionary into url-style string of parameters.
If I have an NSDictionary which looks like this:
dict = [NSDictionary dictionaryWithObjectsAndKeys:#"blue", #"color", #"large", #"size", nil]];
Then how would I turn that into a string that looks like this:
"color=blue&size=large"
EDIT
Thanks for the clues below. This should do it:
NSMutableString *parameterString;
[dict enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
[parameterString appendFormat:#"%#=%#&", key, obj];
}];
parameterString = [parameterString substringToIndex:[string length] - 1];
Quite same solution but without the substring:
NSMutableArray* parametersArray = [[[NSMutableArray alloc] init] autorelease];
[dict enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
[parametersArray addObject:[NSString stringWithFormat:#"%#=%#", key, obj]];
}];
NSString* parameterString = [parametersArray componentsJoinedByString:#"&"];
Create a mutable string, then iterate the dictionary getting each key. Look up the value for that key, and add the key=value& to the string. When you finish that loop, remove the last &.
I presume this is going to be fed through a URL, you will also want to have some method that encodes your strings, in case they contain items like & or +, etc.
NSMutableString* yourString = #"";
for (id key in dict) {
[yourString appendFormat:#"%#=%#&", key, ((NSString*)[dict objectForKey:key])];
}
NSRange r;
r.location = 0;
r.size = [yourString length]-1;
[yourString deleteCharactersInRange:r];
Related
So I have a NSString with a url like this:
NSString stringWithFormat:#"/reading.php?title=blah&description="blah"&image_url=blah... "
what is the best way to append query string to this string? is there a dictionary kind of way to do this?
What you want to do is this.
[NSString stringWithFormat:#"/reading.php?title=blah&description=%#&image_url=blah... ",blah];
Basically %# in the context meaning that you'll pass use a dynamic value which will be a string.
How about a category?
This is not great but for a first pass should give you something to get started
#interface NSDictionary (ps_additions)
- (NSString *)ps_URLParamsValue;
#end
#implementation NSDictionary (ps_additions)
- (NSString *)ps_URLParamsValue;
{
NSMutableString *params = [NSMutableString string];
[self enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop){
[params appendFormat:#"%#=%#&", key, obj];
}];
return [params copy];
}
#end
This would end up with something like:
NSDictionary *params = [NSDictionary dictionaryWithObjectsAndKeys:#"42", #"special_number", #"value", #"another", nil];
NSString *myString = [NSString stringWithFormat:#"/reading.php?%#", [params URLParamsValue]];
NSLog(#"%#", myString);
#=> 2012-03-20 23:54:55.855 Untitled[39469:707] /reading.php?another=value&special_number=42&
You can use something like:
NSString *parameter1 = #"blah";
NSString *parameter2 = #"anotherblah";
NSString *fullURL = [NSString stringWithFormat:#"/reading.php?title=%#&image_url=%#", parameter1, parameter2];
You can add as many parameters as you want. Use "%#" where you will be dynamically adding the text.
Good luck :)
Copy pasting from Paul.s - which is the correct answer, imo - and fixing a (most likely inconsequential) problem of a dangling ampersand...
#interface NSDictionary (ps_additions)
- (NSString *)ps_URLParamsValue;
#end
#implementation NSDictionary (ps_additions)
- (NSString *)ps_URLParamsValue;
{
if (!self.count) return #"";
NSMutableString *params = [NSMutableString string];
[self enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop){
[params appendFormat:#"%#=%#&", key, obj];
}];
// return everything except that last ampersand
return [[params copy] substringToIndex:[params length]-1];
}
#end
Here's a bit of a newbie question.
I have a NSMutableDictionary *dict
which in the log looks like this:
"test1" = "5";
"test2" = "78";
"test3" = "343";
"test4" = "3";
I need to print each number by itself, but I'm pretty poor at arrays and FOR-sentences.
I was thinking something like:
for (dict) {
double number = [[[dict allKeys] objectAtIndex:0] doubleValue];
NSLog(#"Number: %f",number);
}
Which I want to look like this in the log on each line:
Number: 5
Number: 78
Number: 343
Number: 3
But obviously my "FOR"-method is gibberish.
Any help would be appreciated.
You use a fast enumeration for to do this. It iterates over all the keys in the dictionary:
for (NSString *key in dict) {
double number = [[dict objectForKey:key] doubleValue];
NSLog(#"Number: %f", number);
}
Using blocks:
NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:
#"5", #"test1",
#"78", #"test2",
#"343", #"test3",
#"3", #"test4",
nil];
[dictionary enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
NSLog(#"Number: %#", obj);
}];
NSLog output:
Number: 5
Number: 3
Number: 343
Number: 78
If you just want to log these numbers, try the following:
for (NSString *number in dict) {
NSLog(#"Number: %#",[dict objectForKey:number]);
}
The first answer has two objects being created with the name "number". Instead do:
for (NSString *key in dict) {
NSLog(#"Number as double: %f", [[dict objectForKey:key] doubleValue]);
NSLog(#"Number as string: %#", [dict objectForKey:key]);
}
What's great about fast enumeration is that it creates the object for you (and auto-release them). The key is what's being given to you when fast-enumerating through NSDictionaries. Because you now have the key, you just grab the objectAtKey. In your case, it's a string in your dictionary, so you'll have to either convert it to a double (or whatever type you need), or output as a string. I added examples for both cases above. Good luck!
As already mentioned fast-enumeration is preferable in these cases, but you could also do something like this:
for (int i =0; i<[dict count]; i++){
NSString *str=[dict objectForKey:[NSString stringWithFormat:#"test%d",i+1]];
NSLog(#"%#",str);
}
I am having an array like fallowing,
NSArray*array = [NSArray arrayWithObjects:#"1.1 something", #"1.2 something else", #"1.3 out of left field", #"1.4 yet another!", nil];
Now,i am having the string like fallowing,
NSString*str = #"1.3";
Now i will send the str .Then it needs to find that str in array and it need to return the index of object where that text found.Means i need index 2 has to come as output.Can anyone share the code please.Thanks in advance.
Here is an example using blocks, notice the method: hasPrefix:
NSArray *array = [NSArray arrayWithObjects:#"1.1 problem1", #"1.2 problem2", #"1.3 problem3", #"1.4 problem4", nil];
NSString *str = #"1.3";
NSUInteger index = [array indexOfObjectPassingTest:
^(id obj, NSUInteger idx, BOOL *stop) {
return [obj hasPrefix:str];
}];
NSLog(#"index: %lu", index);
NSLog output:
index: 2
First a comment,
NSString *str = 1.3;
does not create an NSString object. You should instead have
NSString *str = #"1.3";
To search the NSArray, you will either have to change the string to the exact string in the array or search the NSString as well. For the former, simply do
float num = 1.3;
NSString *str = [NSString stringWithFormat:#"%.1f problem%d",num,(num*10)%10];
[array indexOfObject:str];
You can get fancier using NSPredicates as well.
Try
NSString *searchString = [str stringByAppendingFormat: #" problem%#", [str substringFromIndex: 2]];
NSUInteger index = [array indexOfObject: searchString];
Or (because you somehow like oneliners):
[array indexOfObject: [[array filteredArrayUsingPredicate: [NSPredicate predicateWithFormat: #"SELF beginswith %#", str]] objectAtIndex: 0]];
The simplest way is to enumerate through values of array and check substrings:
NSArray *array = [NSArray arrayWithObjects: #"1.1 something", #"1.2 something else", #"1.3 out of left field", #"1.4 yet another!", nil];
NSString *str = #"1.33";
int i = -1;
int index = -1;
for (NSString *arrayString in array) {
i++;
if ([arrayString rangeOfString: str].location != NSNotFound) {
index = i;
break;
}
}
NSLog(#"Index: %d", index);
Not optimal but will work.
I have and array of many strings.
I wan't to sort them into a dictionary, so all strings starting the same letter go into one array and then the array becomes the value for a key; the key would be the letter with which all the words in it's value's array begin.
Example
Key = "A" >> Value = "array = apple, animal, alphabet, abc ..."
Key = "B" >> Value = "array = bat, ball, banana ..."
How can I do that?
Thanks a lot in advance!
NSArray *list = [NSArray arrayWithObjects:#"apple, animal, bat, ball", nil];
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
for (NSString *word in list) {
NSString *firstLetter = [[word substringToIndex:1] uppercaseString];
NSMutableArray *letterList = [dict objectForKey:firstLetter];
if (!letterList) {
letterList = [NSMutableArray array];
[dict setObject:letterList forKey:firstLetter];
}
[letterList addObject:word];
}
NSLog(#"%#", dict);
You can achieve what you want through the following steps:
Create an empty but mutable dictionary.
Get the first character.
If a key for that character does not exist, create it.
Add the word to the value of the key (should be an NSMutableArray).
Repeat step #2 for all keys.
Here is the Objective-C code for these steps. Note that I am assuming that you want the keys to be case insensitive.
// create our dummy dataset
NSArray * wordArray = [NSArray arrayWithObjects:#"Apple",
#"Pickle", #"Monkey", #"Taco",
#"arsenal", #"punch", #"twitch",
#"mushy", nil];
// setup a dictionary
NSMutableDictionary * wordDictionary = [[NSMutableDictionary alloc] init];
for (NSString * word in wordArray) {
// remove uppercaseString if you wish to keys case sensitive.
NSString * letter = [[word substringWithRange:NSMakeRange(0, 1)] uppercaseString];
NSMutableArray * array = [wordDictionary objectForKey:letter];
if (!array) {
// the key doesn't exist, so we will create it.
[wordDictionary setObject:(array = [NSMutableArray array]) forKey:letter];
}
[array addObject:word];
}
NSLog(#"Word dictionary: %#", wordDictionary);
Take a look at this topic, they solves almost the same problem as you — filtering NSArray into a new NSArray in objective-c Let me know if it does not help so I will write for you one more code sample.
Use this to sort the contents of array in alphabetical order, further you design to the requirement
[keywordListArr sortUsingSelector:#selector(localizedCaseInsensitiveCompare:)];
I just wrote this sample. It looks simple and does what you need.
NSArray *names = [NSArray arrayWithObjects:#"Anna", #"Antony", #"Jack", #"John", #"Nikita", #"Mark", #"Matthew", nil];
NSString *alphabet = #"ABCDEFGHIJKLMNOPQRSTUWXYZ";
NSMutableDictionary *sortedNames = [NSMutableDictionary dictionary];
for(int characterIndex = 0; characterIndex < 25; characterIndex++) {
NSString *alphabetCharacter = [alphabet substringWithRange:NSMakeRange(characterIndex, 1)];
NSArray *filteredNames = [names filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"SELF BEGINSWITH[C] %#", alphabetCharacter]];
[sortedNames setObject:filteredNames forKey:alphabetCharacter];
}
//Just for testing purposes let's take a look into our sorted data
for(NSString *key in sortedNames) {
for(NSString *value in [sortedNames valueForKey:key]) {
NSLog(#"%#:%#", key, value);
}
}
I have an NSMutableDictionary with some values in it, and I need to join the keys and values into a string, so
> name = Fred
> password = cakeismyfavoritefood
> email = myemailaddress#is.short
becomes name=Fred&password=cakeismyfavoritefood&email=myemailaddress#is.short
How can I do this? Is there a way to join NSDictionaries into strings?
You can easily do that enumerating dictionary keys and objects:
NSMutableString *resultString = [NSMutableString string];
for (NSString* key in [yourDictionary allKeys]){
if ([resultString length]>0)
[resultString appendString:#"&"];
[resultString appendFormat:#"%#=%#", key, [yourDict objectForKey:key]];
}
Quite same question as Turning a NSDictionary into a string using blocks?
NSMutableArray* parametersArray = [[NSMutableArray alloc] init];
[yourDictionary enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
[parametersArray addObject:[NSString stringWithFormat:#"%#=%#", key, obj]];
}];
NSString* parameterString = [parametersArray componentsJoinedByString:#"&"];
[parametersArray release];