I've got a Plist file in my project that has a number of different arrays; each array is a different category which then contains additional arrays for individual questions. The problem I'm having is accessing the nodes and their values within these arrays.
Code I'm using:
-(IBAction)nextleft {
if (questionCounter > 1) {
questionCounter -= 1;
}
[self nextQuestion];
}
-(IBAction)nextright {
if (questionCounter < 20) {
questionCounter += 1;
}
[self nextQuestion];
}
-(void)nextQuestion {
NSArray *pair;
pair = [categories objectAtIndex:questionCounter];
plistQuestion = [pair objectAtIndex:0];
plistAnswer = [pair objectAtIndex:1];
abbreviation.text = plistQuestion;
}
My categories array is filled from my Plist file with this line;
categories = [NSArray arrayWithContentsOfFile:#"questions.plist"];
You can create a class in which you have two instances of NSString (question & answer) which consist the value of question & answer.Create an array of category which consist of object of that class.
Solution:
NSArray *categories = [NSArray arrayWithContentsOfFile:#"questions.plist"];
for (NSArray *pair in categories)
{
NSString *q = [pair objectAtIndex:0];
NSString *a = [pair objectAtIndex:1];
// process q and a
}
Related
hi i want to display string combination on nslog like this format
abc
bca
acb
and so on
but
my program show me it like this format
permutations =
(
(
c,
b,
a
),
(
b,
c,
a
),
(
c,
a,
b
),
(
a,
c,
b
),
(
b,
a,
c
),
(
a,
b,
c
)
)
this is the code i am using
NSArray *array = [NSArray arrayWithObjects:#"a",#"b",#"c",nil];
NSMutableArray *permutations = nil;
int i = 0;
for (i = 0; i < array.count ; i++){
if (!permutations){
permutations = [NSMutableArray array];
for (NSString *character in array){
[permutations addObject:[NSArray arrayWithObject:character]];
}
} else {
//make copy of permutations array and clean og array
NSMutableArray *aCopy = [permutations copy] ;
[permutations removeAllObjects];
for (NSString *character in array){
//loop through the copy
for (NSArray *oldArray in aCopy){
//check if old string contains looping char..
if ([oldArray containsObject:character] == NO){
//update array
NSMutableArray *newArray = [NSMutableArray arrayWithArray:oldArray];
[newArray addObject:character];
//add to permutations
[permutations addObject:newArray];
}
}
}
}
}
NSLog(#"permutations = \n %#",permutations);
}
kindly tell me how i can display it in my require format
Try this way :
NSString *stringPermuted=[NSString new];
for (NSArray *array in permutations) {
for (NSString *string in array) {
stringPermuted=[stringPermuted stringByAppendingFormat:#"%#",string];
}
stringPermuted=[stringPermuted stringByAppendingFormat:#"\n"];
}
NSLog(#"permutations=\n%#",stringPermuted);
Another Way :
NSString *stringPermuted=[NSString new];
for (NSArray *array in permutations) {
stringPermuted=[stringPermuted stringByAppendingFormat:#"%#\n",[array componentsJoinedByString:#""]];
}
NSLog(#"permutations=\n%#",stringPermuted);
Create a simple method for displaying
- (NSString *)formatPermutations:(NSArray *)permutations {
NSString * formattedPermutations = #"";
for (NSArray * permutation in permutations) {
formattedPermutations = [formattedPermutations stringByAppendingFormat:#"%#\n", [self formatPermutation:permutation]];
}
return formattedPermutation;
}
- (NSString *)formatPermutation:(NSArray *)permutation {
NSString * formattedPermutation = #"";
for (NSString * letter in permutation) {
formattedPermutation = [formattedPermutation stringByAppendingString:letter];
}
return formattedPermutation;
}
and use it
NSLog(#"permutations = \n %#",[self formatPermutations:permutations]);
Another option (and maybe preferable option) would be to create your own classes and PermutationArray and Permutation and override their description method.
Such method is the equivalent of a Java toString and it gets called whenever NSLog needs to get a NSString representation out of an object.
With your last line NSLog(#"permutations = \n %#",permutations); you are logging the entire NSMutableArray in the console. Xcode is formatting it like that to make it more readable.
Try logging your results this way:
Updated version:
for (NSArray *permutation in permutations){
NSMutableString *tempString = [[NSMutableString alloc] initWithString:#""];
for(NSString *character in permutation){
[tempString appendString:character]
}
NSLog(#"%#\n",tempString);
}
Your permutations object is an NSArray of NSArrays. When using NSLog to log it, NSLog will invoke the description method of NSArray and this uses linebreaks to split up eacho f the objects in the array.
If you want to change the way it is printed you can either use your own NSArray subclass and overwrite the description method or just write a slightly more complicated log statement like so:
Quick and Dirty
for (NSArray *arrayOfStrings in permutations) {
for (NSString *oneCharacterString in arrayOfStrings) {
printf("%s", [oneCharacterString UTF8String]);
}
printf(" ");
}
Little bit less quick a lot less dirty
// with linebreaks after each permutation
// If you don't want those, move the NSLog out of the for loop construct one big string to log in the format you like
for (NSArray *arrayOfStrings in permutations) {
NSMutableString *permutationString = [NSMutableString string];
for (NSString *oneCharacterString in arrayOfStrings) {
[permutationString appendString:oneCharacterString]
}
NSLog(permutationString);
}
Other comments: If you want to save only onecharacter anyway you could also use an NSNumber object (create it using [NSNumber numberWithChar:]).
Or you could use NSString or NSMutableString instead of the inner arrays.
I have an application in which i am having the details of the members as a dictionary.i want to add an array with particular object from the dictionary.The response i am having is like this,
{
500 = {
name = baddd;
status = "<null>";
};
511 = {
name = abyj;
status = "Hi all...:-)";
};
512 = {
name = abyk;
status = fdffd;
};
}
I want to create an array with the results of name only.i have tried like this
for(int i=0;i<=self.currentChannel.memberCount;i++)
{
NSString *name=[NSString stringWithFormat:#"%#",[self.currentChannel.members objectForKey:#"name"]] ;
NSLog(#"%#",name);
[searchfriendarray addObject:name];
}
NSLog(#"%#",searchfriendarray);
but the value added is null. can anybody help me ?
Traverse objectEnumerator to get the values (inner dictionaries). Then just add the value of "name" to the resulting array. Example (assuming the dictionary is named d):
NSDictionary* d = ...
NSMutableArray* array = [NSMutableArray arrayWithCapacity:d.count];
for(NSDictionary* member in d.objectEnumerator) {
[array addObject:[member objectForKey:#"name"]];
}
Krumelur was faster than me ;) He is right by saing that you should traverse the dictionary values first. In your implementation you don't reference your counter variable i somewhere, so the NSString name is the same in each iteration.
This may help you..
// here you can get Array of Dictionary First
NSArray *arr = [[NSArray alloc] initWithContentsOfFile:#""]; // get array first from your response
NSDictionary *temp = [[NSDictionary alloc] initWithDictionary:self.currentChannel.members];
for(int i=0;i<=self.currentChannel.memberCount;i++)
{
NSDictionary *temp = [arr objectAtIndex:i];
NSString *name=[NSString stringWithFormat:#"%#",[temp objectForKey:#"name"]] ;
NSLog(#"%#",name);
[searchfriendarray addObject:name];
}
NSLog(#"%#",searchfriendarray);
Thanks.
I have a NSDictionary that contains objects and keys. The Keys hold a Name and number. I would like to insert those objects into a NSMutableArray by using insertObject: atIndex: . Object being the name and the number is the index I would like to place the object in. I now know that NSMutableArrays are able to insert objects at index:6 if there is no 1-5 so how do I make this possible? Any suggestions are very appreciated!
Example Dictionary [dict objectForKey:#"array"]:
preferences as whole (
{
Name = PowerDown;
btnIndex = 3;
},
{
Name = ClearCache;
btnIndex = 5;
},
{
Name = KillBGApps;
btnIndex = 6;
},
{
Name = InfoPanel;
btnIndex = 2;
},
{
Name = Lock;
btnIndex = 4;
},
{
Name = Reboot;
btnIndex = 0;
},
{
Name = Respring;
btnIndex = 1;
}
)
What I have so far but crashes when adding objects out of bounds of the array
-(void)loadArray{
self.buttons = [NSMutableArray array];
NSMutableArray *tempArray = [[NSMutableArray alloc] init];
tempArray = [buttonsPrefs objectForKey:#"buttonsToOrder"];
for(NSDictionary * dict in tempArray)
{
if (dict) {
NSString *btnName = [dict objectForKey:#"Name"];
NSString *btnIndex = [dict objectForKey:#"btnIndex"];
NSUInteger index = [btnIndex integerValue];
NSLog(#"Name = %#",btnName);
NSLog(#"at index %i",index);
[self.buttons insertObject: btnName atIndex: index];
}
}
}
EDIT: These values "indexes" for the names with change when a user moves the cell
- (void) tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath
*)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath {
NSUInteger fromIndex = [fromIndexPath row];
NSUInteger toIndex = [toIndexPath row];
if (fromIndex == toIndex)
return;
NSMutableDictionary *selectedButton = [[[_buttons objectAtIndex:fromIndex] retain]
autorelease];
[_buttons removeObjectAtIndex:fromIndex];
[_buttons insertObject:selectedButton atIndex:toIndex];
//[buttonsPrefs setObject:_buttons forKey:#"buttonsToOrder"];
//[buttonsPrefs writeToFile:[self getFilePath] atomically: YES];
}
Try to fill your target array with some dummy data according to yourDict count like this:
for (int i=0, i<[yourDict count], ++i){
[yourArray addObject:#"dummyData"];
}
And when you will need to insertObject do this:
for(NSDictionary * dict in tempArray)
{
if (dict) {
NSString *btnName = [dict objectForKey:#"Name"];
NSString *btnIndex = [dict objectForKey:#"btnIndex"];
NSUInteger index = [btnIndex integerValue];
[yourArray insertObject:btnName atIndex:index];
[yourArray removeObjectAtIndex:index+1];
}
}
NSMutableArray insertObject: atIndex:
as per apple docs `
"Note that NSArray objects are not like C arrays. That is, even though
you specify a size when you create an array, the specified size is
regarded as a “hint”; the actual size of the array is still 0. This
means that you cannot insert an object at an index greater than the
current count of an array."
Can only fill within valid array value set.Two things you can do.
Sort and fill the array
Fill the array with some default object like a string(cannot be nil) and then replace it.This option is valid if you are filling all the values in array because when used later you have to check weather the value is right there or the default value is in that position
The title pretty much says it all, but just to clarify: I have an NSMutableDictonary containing several NSMutableArrays. What I would like to do is find any value that is present in multiple arrays (there will not be any duplicates in a single array) and return that value. Can someone please help? Thanks in advance!
Edit: For clarity's sake I will specify some of my variables:
linesMutableDictionary contains a list of Line objects (which are a custom NSObject subclass of mine)
pointsArray is an array inside each Line object and contains the values I am trying to search through.
Basically I am trying to find out which lines share common points (the purpose of my app is geometry based)
- (NSValue*)checkForDupes:(NSMutableDictionary*)dict {
NSMutableArray *derp = [NSMutableArray array];
for (NSString *key in [dict allKeys]) {
Line *temp = (Line*)[dict objectForKey:key];
for (NSValue *val in [temp pointsArray]) {
if ([derp containsObject:val])
return val;
}
[derp addObjectsFromArray:[temp pointsArray]];
}
return nil;
}
this should work
If by duplicates you mean returning YES to isEqual: you could first make an NSSet of all the elements (NSSet cannot, by definition, have duplicates):
NSMutableSet* allElements = [[NSMutableSet alloc] init];
for (NSArray* array in [dictionary allValues]) {
[allElements addObjectsFromArray:array];
}
Now you loop through the elements and check if they are in multiple arrays
NSMutableSet* allDuplicateElements = [[NSMutableSet alloc] init];
for (NSObject* element in allElements) {
NSUInteger count = 0;
for (NSArray* array in [dictionary allValues]) {
if ([array containsObject:element]) count++;
if (count > 1) {
[allDuplicateElements addObject:element];
break;
}
}
}
Then you have your duplicate elements and don't forget to release allElements and allDuplicateElements.
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);
}
}