Get the correct index of dictionary - objective-c

NSMutableArray *tmpMutArr = [NSMutableArray arrayWithArray:allObjectsArray];
NSLog(#"The content of array is%#",tmpMutArr);
int index;
for (int i=0;i<[tmpMutArr count];i++)
{
if([[tmpMutArr objectAtIndex:i] isKindOfClass:[NSDictionary class]])
{
NSMutableDictionary *tempDict = [tmpMutArr objectAtIndex:i];
if([[tempDict valueForKey:#"Name"] isEqualToString:[NSString stringWithFormat:#"%#", nameString]])
{
index = i;
}
}
}
[tmpMutArr replaceObjectAtIndex:index withObject:[NSDictionary dictionaryWithDictionary:mutDict]];
This code is not replacing the matching object in tmpMutArr as I want it to, but replaces all objects in tmpMutArr instead. How to replace only the index I want?
I know that tmpMutArr containing all objects before the replacement, so I just need to specify the index correctly I think. How to do so?

NSMutableArray *tmpMutArr = [NSMutableArray arrayWithArray:allObjectsArray];
NSLog(#"The content of array is%#",tmpMutArr);
int index;
for (int i=0;i<[tmpMutArr count];i++)
{
if([[tmpMutArr objectAtIndex:i] isKindOfClass:[NSDictionary class]])
{
NSMutableDictionary *tempDict = [tmpMutArr objectAtIndex:i];
if([[tempDict valueForKey:#"Name"] isEqualToString:nameString])
{
index = i;
break; // << added break
}
}
}
[tmpMutArr replaceObjectAtIndex:index withObject:[NSDictionary dictionaryWithDictionary:mutDict]];

maybe, you should try to this version... you have not specified which index is needed, I suppose the first one.
for (int i=0;i<[tmpMutArr count];i++) {
if([[tmpMutArr objectAtIndex:i] isKindOfClass:[NSDictionary class]]) {
NSMutableDictionary *tempDict = [tmpMutArr objectAtIndex:i];
if([[tempDict valueForKey:#"Name"] isEqualToString:[NSString stringWithFormat:#"%#", nameString]]) {
index = i;
break; // when you find the first one, you should go out from the iteration
}
}
}

Related

Find a dictionary in ArrayOfDictionaries with a specific keyvalue pair

I have an array of dictionaries
for(int i = 0; i < 5; i++) {
NSMutableDictionary *_myDictionary = [NSMutableDictionary dictionary];
[_myDictionary setObject:[NSString stringWithFormat:#"%d",i] forKey:#"id"];
[_myDictionary setObject:label.text #"Name"];
[_myDictionary setObject:label1.text #"Contact"];
[_myDictionary setObject:label2.text #"Gender"];
}
[_myArray addObject:_myDictionary];
Now I want to pick a dictionary from the array whose objectForKey:#"id" is 1 or 2 or something else like there is an sql query Select * from Table where id = 2.
I know this process
int index = [_myArray count];
for(int i = 0; i < 5; i++)
{
NSMutableDictionary *_myDictionary = [NSMutableDictionary dictionaryWithDictionary:[_myArray objectAtIndex:i]];
if([[_myDictionary objectForKey:#"id"] isEqualToString:id])
{
index = i;
return;
}
}
if(index != [_myArray count])
NSLog(#"index found - %i",index);
else
NSLog(#"index not found");
Any help would be appreciated.
Thanks in Advance !!!
Try this, this is by using fast enumeration
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
for(dict in _myArray)
{
if([[dict valueForKey:#"id"] isEqualToString:#"1"])
{
return;
}
}
You should use [NSNumber numberWithInteger: i] not a NSString.
Code fore this search should look like this:
NSString *valueToFind = [NSString stringWithFormat:#"%d", intValue]; // [NSNumber numberWithInteger: intValue]
NSInteger index = [_myArray indexOfObjectPassingTest:^BOOL(NSDictionary *obj, NSUInteger idx, BOOL *stop) {
return [valueToFind isEqualToString: [obj objectForKey: #"id"]];
}];
NSDitionary *found = [_myArray objectAtIndex: index];

Objective-C NSMutableArray

I have filled a NSMutableArray with integer and string values from my database.
The problem is that many values were inserted more than once.
Using the following code I remove duplicate objects
for (id object in originalArray) {
if (![singleArray containsObject:object]) {
[singleArray addObject:object];
}
}
Bus this works only if the objects are exactly the same between them.
Is there a way to remove duplicates based on the integer value?
EDIT (from an OP's comment on a deleted answer)
I have some objects containing int and NSString. For example #"John 13", #"Mary 25", #"Luke 25", #"Joan 13". The NSMutableArray will contain all four names and duplicates of 13, 25. I want to remove the duplicates leaving 13 and 25 only once in the array. I do not care which names will be removed. Care only for the integer values to use them later.
If your elements are all NSNumber objects:
for (int i=0;i<array.count;i++) {
for (int j=i+1;j<array.count;j++) {
if ([array[i] isEqualToNumber:array[j]]) {
[array removeObjectAtIndex:j--];
}
}
}
Or if all objects are either integer NSNumbers or NSStrings containing integer values:
for (int i=0;i<array.count;i++) {
for (int j=i+1;j<array.count;j++) {
if ([array[i] intValue] == [array[j] intValue]) {
[array removeObjectAtIndex:j--];
}
}
}
Try this:
// singleArray is initially empty
for (id object in originalArray)
{
BOOL contains= YES;
for( id single in singleArray)
{
if( [single integerValue]==[object integerValue] )
{
contains= NO;
break;
}
}
if(contains)
{
[singleArray addObject: object];
}
}
no test, tell me if it does not work. assuming objects in the array are string and format is "WORD NUMBER"
Boolean myEqual(const void *value1, const void *value2) {
NSString *str1 = (__bridge NSString *)(value1);
NSString *str2 = (__bridge NSString *)(value2);
NSArray *arr1 = [str1 componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
NSArray *arr2 = [str2 componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
return [[arr1 lastObject] isEqual:[arr2 lastObject]];
}
CFHashCode myHash(const void *value) {
NSString *str1 = (__bridge NSString *)(value);
NSArray *arr1 = [str1 componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
return [[arr1 lastObject] hash];
}
NSMutableArray *array = // your array;
CFSetCallBacks callBacks = kCFTypeSetCallBacks;
callBacks.equal = myEqual;
callBacks.hash = myHash;
CFMutableSetRef set = CFSetCreateMutable(NULL, [array count], &callBacks);
for (id obj in [array copy]) { // copy so can modify the original array
if (CFSetContainsValue(set, (__bridge const void *)(obj))) {
[array removeObject:obj];
} else {
CFSetAddValue(set, (__bridge const void *)(obj));
}
}

NSMutableArray to NSString conversion

Here is the string from NSMutableArray:
(
(
"Some String Value"
)
)
This code displays the string value that I want, but however, it displays with the brackets and quotes. How do I remove them?
Thank you in advance!!
In your case it is 2D Array:
Something like this:
NSArray *arr=[NSArray arrayWithObject:#"asdf"];
NSArray *arr2=[NSArray arrayWithObjects:arr, nil];
You need to go to 2nd level to retrive it as :
NSLog(#"=> %#",arr2[0][0]);
NSString *string=arr2[0][0];
-(void)repeatArray:(NSArray *)array1
{
static NSMutableString *InsideString; // Better to use global Varaible declared in ViewDidLoad/loadView
NSArray *array = array1; //Its your array
for (int i = 0; i< [array count]; i++) {
if ([[array objectAtIndex:i] isKindOfClass:[NSArray class]]) {
[self repeatArray:[array objectAtIndex:i]];
} else if ([[array objectAtIndex:i] isKindOfClass:[NSString class]]) {
[InsideString appendString:[NSString stringWithFormat:#"%# ", [array objectAtIndex:i]]];
}
}
}

Obj-C, function to return index of nsstring found in nsarray?

I've been looking to see if I can find a function like indexOf.
I have an array.
self.data = [[NSArray alloc] initWithObjects:#"apple", #"lemon", #"pear", nil];
Looking for a function to return which would look for lemon and return 1 ?
how about indexOfObject:?
NSUInteger index = [self.data indexOfObject:#"lemon"];
Try this method.
-(int)indexOfString:(NSString *)string inArray:(NSArray *)array {
for(int i=0; i<[array count]; i++) {
if ([[array objectAtIndex:i] class] == [NSString class]) {
if ([[array objectAtIndex:i] isEqualToString:string]) {
return i;
}
}
}
}
EDIT: The other answer using -indexOfObject: is better.

Get matched string from two NSArrays

How can I save the string that match from one NSArray with one index difference in NSMutableArray?
For example, there are three "apple", four "pineapple", six "banana", two "cocoa" and the rest of words dont have duplicate(s) in the nsarray, i would like to know if the nsarray has at least two same words. If yes, I would like to save "apple", "pineapple, "banana" and "cocoa" once in nsmutablearray. If there are other alike words, I would like to add them to namutablearray too.
My code (which still doesn't work properly);
NSArray *noWords = [[NSArray alloc] initWithArray:
[[NSString stringWithContentsOfFile:[[NSBundle mainBundle]
pathForResource:#"words" ofType:#"txt"]
encoding:NSUTF8StringEncoding error:NULL]
componentsSeparatedByString:#"\n"]];
NSUInteger scount = [noWords count];
int ii = 0;
NSString *stringline;
for (ii; ii < scount; ii++)
{
stringline = [noWords objectAtIndex:ii];
NSLog(#"stringline : %# ", stringline);
}
int i = 1;
NSString *line;
for (i ; i < 10; i++)
{
line = [noWords objectAtIndex:i];
NSLog (#"line : %# ", line);
NSMutableArray *douwords = [NSMutableArray array];
if ([stringline isEqualToString:line])
{
NSString *newword;
for (newword in douwords)
{
[douwords addObject:newword];
NSLog (#"detected! %# ", douwords);
}
}
}
Here's a solution using two sets:
- (NSArray *)getDuplicates:(NSArray *)words
{
NSMutableSet *dups = [NSMutableSet set],
*seen = [NSMutableSet set];
for (NSString *word in words) {
if ([seen containsObject:word]) {
[dups addObject:word];
}
[seen addObject:word];
}
return [dups allObjects];
}
Assuming NSSet uses hash tables behind the scenes (which I'm betting it does), this is going to be faster than the previously suggested O(n^2) solution.
Here's something off the top of my head:
NSMutableSet* duplicates = [NSMutableSet set];
NSArray* words = [NSArray arrayWithObjects:#"Apple", #"Apple", #"Orange", #"Apple", #"Orange", #"Pear", nil];
[words enumerateObjectsUsingBlock:^(NSString* str, NSUInteger idx, BOOL *stop) {
for (int i = idx + 1; i < words.count; i++) {
if ([str isEqualToString:[words objectAtIndex:i]]) {
[duplicates addObject:str];
break;
}
}
}];
NSLog(#"Dups: %#", [duplicates allObjects]); // Prints "Apple" and "Orange"
The use of an NSSet, as opposed to an NSArray, ensures strings are not added more than once. Obviously, there are optimizations that could be done, but it should be a good starting point.
I assume that you want to count appearances of words in your array and output those with a count of more than one. A basic and verbose way to do that would be:
// Make an array of words - some duplicates
NSArray *wordList = [[NSArray alloc] initWithObjects:
#"Apple", #"Banana", #"Pencil",
#"Steve Jobs", #"Kandahar",
#"Apple", #"Banana", #"Apple",
#"Pear", #"Pear", nil];
// Make an mutable dictionary - the key will be a word from the list
// and the value will be a number representing the number of times the
// word appears in the original array. It starts off empty.
NSMutableDictionary *wordCount = [[NSMutableDictionary alloc] init];
// In turn, take each word in the word list...
for (NSString *s in wordList) {
int count = 1;
// If the word is already in the dictionary
if([wordCount objectForKey:s]) {
// Increse the count by one
count = [[wordCount objectForKey:s] intValue] + 1;
}
// Save the word count in the dictionary
[wordCount setObject:[NSNumber numberWithInt:count] forKey:s];
}
// For each word...
for (NSString *s in [wordCount keysOfEntriesPassingTest:
^(id key, id obj, BOOL *stop) {
if ([obj intValue] > 1) return YES; else return NO;
}]) {
// print the word and the final count
NSLog(#"%2d %#", [[wordCount objectForKey:s] intValue], s);
}
The output would be:
3 Apple
2 Pear
2 Banana