0

The title can be a little unclear. But here is what i want to achieve:

I have an NSMutableArray with custom object e.g.

[
Custom Object 1,
Custom Object 2,
Custom Object 3,
..
..
..
Custom Object 10
]

The Custom object Consists of following variables:

id, name, date, seen_count;

I have the value of id e.g.10.

Now I want get the Index of the custom object where id=10 within NSMutableArray, so that i can update that object and reload a particular Row/Cell within UITableView to reflect the changes.

P.S: One way to do is to loop through the array. But is there any other way to achieve this?

Bista
  • 7,869
  • 3
  • 27
  • 55

3 Answers3

2

Use NSPredicate::

CustomObject *object= [[[yourArray filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"id == 10"]] lastObject];

// make changes in object.

Get Index of Object in array::

NSUInteger positionOfChange =  [yourArray indexOfObject:object];

// update your cell that is on position positionOfChange integer value

Hope this will help and sorry for any typo in code snippet.

Note :: if you are not confirm that object will always there for id than first check that filtered array has object and then go further otherwise it will crash. Don't check lastobject in filteredArrayUsingPredicate if you are not sure.

KDeogharkar
  • 10,939
  • 7
  • 51
  • 95
2

Since an array can only be accessed by index, iterating through the array is the only way. You can loop explicitly, looking for the appropriate object or implicitly using the indexOfObjectPassingTest method of NSArray. The advantage of this approach is that it only has to iterate as far as the first match, while filteredArrayUsingPredicate needs to iterate the whole array.

NSInteger objectIndex=[myArray indexOfObjectPassingTest:^BOOL(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
    CustomObject *myObject=(CustomObject *)obj;
    if (obj.id==targetid) {   // Assumes id is an int, change the test as appropriate if it is a string or other object
        *stop=YES;
    }
}];

Another approach is to use an auxiliary NSDictionary that stores the index of the object. This requires a single iteration of the array to build the dictionary but allows you to locate a given object more quickly.

For convenience I will assume that id in this case is a string; if it is an int then you need to box it in an NSNumber:

NSMutableDictionary auxDict=[NSMutableDictionary new];
for (i=0;i<myArray.count;i++) {  
   CustomObject *obj=myArray[i];
   [auxDict addObject:[NSNumber numberWithInt:i] forKey:obj.id];
}

Then, to access an object, simply use the dictionary

NSNumber *indexNumber=auxDict[targetId];
int index=[indexNumber intValue];
CustomObject *object=myArray[index];
Paulw11
  • 108,386
  • 14
  • 159
  • 186
1
    NSString *search=@"5";
    NSInteger index=-1;
    if ([[arr valueForKey:@"id"] containsObject:search]) {
        index=[arr1 indexOfObject:search];

    }
    if (index!=-1) {
        //do whatever with your index
    }
  • Would you mind explaining your answer? – Yassin Hajaj Dec 19 '15 at 21:18
  • 1
    This is a fairly inefficient solution - first it creates a new array that contains the value of the `id` property of the objects in the first array, then it checks to see if the desired `id` is in this new array (iterating the array in the process), then it obtains the index of the matching object (iterating the array again) making it O3n. You could simply use `indexOfObject` to start with and check for the special result `NSNotFound` rather than using `containsObject` but that will still make it O2n – Paulw11 Dec 20 '15 at 00:28
  • You can simply do it with creating new array. This would also make it O2n. – Mohit Mathur Dec 21 '15 at 06:54