Remove certain objects from NSMutableArray [duplicate] - iphone

This question already has answers here:
Removing object from NSMutableArray
(5 answers)
Closed 9 years ago.
I have an NSMutableArray of objects which are of AdDetail class that hold a few properties (for eg. adId, adTitle, adPrice... etc). I want to remove only those objects which have adID = 0. How can I do that ?

Perhaps something more elegant would suffice?
[array removeObjectsInArray:[array filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"adID == 0"]]];

Using predicate
NSArray *filtered=[array filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"(adId == 0)"]];
Using fastEnumeration:
NSMutableArray *newArray=[NSMutableArray new];
for(AdDetail adDetailObj in array){
if(![[adDetailObj adId] isEqualToString:#"0"]){ //if these are strings, if NSInteger then directly compare using ==
newArray[newArray.count]=adDetailObj;
}
}
Now newArray contains all objects other than id=0

Use following code :
int count = array.count;
for(i=0;i<count;i++){
ADetail *adetail = [array objectAtIndex:i];
if(adetail.adID = 0){
[array removeObjectAtIndex:i];
i--;
}
count = array.count;
}

NSMutableArray *newArray = [NSMutableArray arrayWithArray:yourArray];
for (int i = 0; i < yourArray.count; i++)
{
AdDetail *obj = (AdDetail *)[yourArray objectAtIndex:i];
if (obj.adID == 0)
[newArray removeObjectAtIndex:i];
}
yourArray = [newArray mutableCopy];

for(i=0; i < myArray.count; i++)
{
myClass = [myArray objectAtIndex:i];
if([myClass.adID isEqualtoString:"0"])// if it it int/NSInteger the write myClass.adID==0
{
[myArray removeObjectAtIndex:i];
i--;
}
}

predicate = #"adID == 0";
newArray = [theArray filterUsingPredicate:aPredicate]

Related

Sort NSArray for a specific order

I have an NSArray of custom objects.
Each object contains one integer value for ex. 1,2,3,4
Now I want to sort Array like below
9 7 5 3 1 2 4 6 8
Could some one help me?
Here is your answer.
Hope your first array is in sorted order (ascending) if not then you need to sort it first.
NSMutableArray *myArray = [NSMutableArray array];
//Populate your array with custom objects. I had created my own which contain an integer type property.
[myArray addObject:[[myObject alloc] initWithId:11 objectName:#"K"]];
[myArray addObject:[[myObject alloc] initWithId:3 objectName:#"C"]];
[myArray addObject:[[myObject alloc] initWithId:4 objectName:#"D"]];
....
...
.... and so on
then sort it in Ascending order. You can do it Descending also but then you need to change the below logic little bit. I showing with Ascending order.
NSArray *tempArray = [myArray sortedArrayUsingComparator:^NSComparisonResult(myObject *obj1, myObject *obj2) {
if([obj1 objectId] > [obj2 objectId]) return NSOrderedDescending;
else if([obj1 objectId] < [obj2 objectId]) return NSOrderedAscending;
else return NSOrderedSame;
}];
Now sort them as per your requirement
NSMutableArray *finalArray = [NSMutableArray arrayWithArray:tempArray];
NSInteger totalObjects = [tempArray count];
NSInteger centerObjectIndex = totalObjects>>1;
__block NSInteger rightPosition = centerObjectIndex + 1;
__block NSInteger leftPosition = centerObjectIndex - 1;
__block BOOL toggle = NO;
[tempArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
if(idx == 0) [finalArray replaceObjectAtIndex:centerObjectIndex withObject:obj];
else
{
if(toggle)
{
if(leftPosition >= 0)
{
[finalArray replaceObjectAtIndex:leftPosition withObject:obj];
leftPosition -= 1;
}
}
else
{
if(rightPosition < totalObjects)
{
[finalArray replaceObjectAtIndex:rightPosition withObject:obj];
rightPosition += 1;
}
}
toggle = !toggle;
}
}];
Here is the final step if your array contains an even numbers of objects
if(!(totalObjects % 2))
{
[finalArray removeObjectAtIndex:0];
[finalArray addObject:[tempArray objectAtIndex:totalObjects-1]];
}
Now you are at end. Your array named finalArray get sorted as per your requirement.

About NSMutableArray add NSArray issue

I want to below effect,but I don't kown how to use NSMutableArray combine NSArray More than two?
1.my code
for (int i=0; i<[DateSortArry2 count]; i++) {
for (int j=0; j<[DateSortArry2Copy count]; j++) {
NSString *sectiondateStr2 = [NSString stringWithFormat:#"%#",[DateSortArry2Copy objectAtIndex:j]];
if ([[DateSortArry2 objectAtIndex:i] isEqualToString:sectiondateStr2]) {
[Arry addObject:sectiondateStr2];
}
}
[SumArry addObjectsFromArray:Arry];
[Arry removeAllObjects];
}
2.my code Result
SumArry:(
"20130227",
"20130227",
"20130227",
"20130226",
"20130226",
"20130226",
"20130225",
"20130225")
3.I want the results
SumArry:((
"20130227",
"20130227",
"20130227",
),
(
"20130226",
"20130226",
"20130226",
),
(
"20130225",
"20130225"
))
Your code repeatedly fills and empties the same array by adding its elements, but you need to preserve the structure with additional instances of NSArray. So, use a new NSArray for each section.
for (int i=0; i<[DateSortArry2 count]; i++) {
NSMutableArray *section = [NSMutableArray array];
for (int j=0; j<[DateSortArry2Copy count]; j++) {
NSString *sectiondateStr2 = [NSString stringWithFormat:#"%#",[DateSortArry2Copy objectAtIndex:j]];
if ([[DateSortArry2 objectAtIndex:i] isEqualToString:sectiondateStr2]) {
[section addObject:sectiondateStr2];
}
}
[SumArry addObject:section];
}
You can either store a reference to another array (or any type of object) in your array:
[myMutableArray addObject:otherArray];
Or concatinate the arrays.
[myMutableArray addObjectsFromArray:otherArray];
Both of which are documented in the documentation. By the looks of it the first approach is what you want since you want to have NSArray of NSMutableArray.
try this:
please tell me if it works.
thanks
NSString *str = #"";
for (int i=0; i<[DateSortArry2 count]; i++)
{
if (str isEqualToString:[DateSortArry2 objectAtIndex:i])
{
return;
}
else
{
NSMutableArray * Arry = [[NSMutableArray alloc] init];
str = [DateSortArry2 objectAtIndex:i]
for (int j=0; j<[DateSortArry2Copy count]; j++)
{
if ([[DateSortArry2 objectAtIndex:i] isEqualToString:str])
{
[Arry addObject:str];
}
}
[SumArry addObject:Arry];
[Arry removeAllObjects];
}
}

How to sort an array with alphanumeric values?

I have an array which contains strings like frame_10#3x.png , frame_5#3x.png,frame_19#3x.png etc.
So I want to sort this array according to the number after the underscore i.e. the correct sequence will be frame_5#3x.png,frame_10#3x.png,frame_19#3x.png.
I tried to use the following method but no result:
NSInteger firstNumSort(id str1, id str2, void *context) {
int num1 = [str1 integerValue];
int num2 = [str2 integerValue];
if (num1 < num2)
return NSOrderedAscending;
else if (num1 > num2)
return NSOrderedDescending;
return NSOrderedSame;
}
Please suggest how to do this sorting for array.
NSArray *sry_img = [[NSArray alloc] initWithObjects:#"frame_18#3x.png",#"frame_17#3x.png",#"frame_1222#3x.png",#"frame_10#3x.png",#"frame_3#3x.png",#"frame_4#3x.png",#"frame_4#3x.png",#"frame_1#3x.png",#"frame_4#3x.png",#"frame_4#3x.png",nil];
NSArray *sortedStrings = [sry_img sortedArrayUsingSelector:#selector(localizedStandardCompare:)];
NSLog(#"%#",sortedStrings);
Enjy .......
But
localizedStandardCompare:, added in 10.6, should be used whenever file names or other strings are presented in lists and tables where Finder-like sorting is appropriate. The exact behavior of this method may be tweaked in future releases, and will be different under different localizations, so clients should not depend on the exact sorting order of the strings.
you want to do something like:
NSArray *components1 = [str1 componentsSeparatedByString:#"_"];
NSArray *components2 = [str2 componentsSeparatedByString:#"_"];
NSString *number1String = [components1 objectAtIndex:([components1 count] - 1])];
NSString *number2String = [components2 objectAtIndex:([components2 count] - 1])];
return [number1String compare:number2String];
I am not sure if my solution is the best possible approach but it can solve your problem for the time being :) .
1) First I have written a function to get the numbers before # character in your string and then I implemented simple SELECTION SORT algo to sort the array using this functions.
- (NSString*)getSubStringForString:(NSString*)value {
// First we will cut the frame_ string
NSMutableString *trimmedString = [NSMutableString stringWithString:[value substringWithRange:NSMakeRange(6, [value length]-6)]];
// New String to contain the numbers
NSMutableString *newString = [[NSMutableString alloc] init];
for (int i = 0; i < [trimmedString length] ; i++) {
NSString *singleChar = [trimmedString substringWithRange:NSMakeRange(i, 1)];
if (![singleChar isEqualToString:#"#"]) {
[newString appendString:singleChar];
} else {
break;
}
}
return newString;
}
This is the selection Implementation of the algo for sorting. The main logic is in the for loop. You can copy the code in viewDidLoad method to test.
NSMutableArray *array = [[NSMutableArray alloc] initWithObjects:#"frame_10#3x.png",#"frame_5#3x.png",
#"frame_3#3x.png", #"frame_19#3x.png",
nil];
NSLog(#"Values before Sort: %#", array);
int iPos;
int iMin;
for (iPos = 0; iPos < [array count]; iPos++)
{
iMin = iPos;
for (int i = iPos+1; i < [array count]; i++)
{
if ([[self getSubStringForString:[array objectAtIndex:i]] intValue] >
[[self getSubStringForString:[array objectAtIndex:iMin]] intValue]) {
iMin = i;
}
}
if ( iMin != iPos )
{
NSString *tempValue = [array objectAtIndex:iPos];
[array replaceObjectAtIndex:iPos withObject:[array objectAtIndex:iMin]];
[array replaceObjectAtIndex:iMin withObject:tempValue];
}
}
NSLog(#"Sorted Values: %#", array);
I hope that it can atleast keep you going. :)
You can try this-
NSString *str1 = [[[[str1 componentsSeparatedByString:#"frame_"] objectAtIndex:1] componentsSeparatedByString:#"#3x.png"] objectAtIndex:0];
int num1 = [str1 integerValue];

How to get index in an NSArray?

NSMutableArray*array = [[NSMutableArray alloc]init];
NSArray*Somearray = [NSArray arrayWithObjects:1st Object,2ndObject,3rd Object,4th object,5th Object,nil];
In the above array 1st Object,2ndObject,3rd Object,4th object,5th Object having val,content,conclusion in each index.
for(int i=0;i<[Somearray count];i++)
{
______________
Here the code is there to give each index ,that is having val,content,conclusion ..
After that val,content,conclusion in each index will be add to Dict..
____________
NSDictionary *Dict = [NSDictionary dictionaryWithObjectsAndKeys:val,#"val",content,#"content",conclusion,#"conclusion",nil];
//Each time adding dictionary into array;
[array addObject:Dict];
}
The above Dictionary is in for loop and the keyvalue pairs will be add 5 times(Somearray Count).Now array is having in
array = [{val="1.1 this is first one",content="This is the content of 0th index",conclusion="this is the conclusion of 0th index"},{val="1.2 this is first one",content="This is the content of 1st index",conclusion="this is the conclusion of 1st index"},____,____,______,{val="1.5 this is first one",content="This is the content of 4th index",conclusion="this is the conclusion of 4th index"},nil];
Now i am having NSString*string = #"1.5";
Now i need the index where val is having 1.5 in it.How to send the str in to array to find the the index.
Can anyone share the code please.
Thanks in advance.
Use method indexOfObject
int inx= [array indexOfObject:#"1.5"];
For Find index particular key value.
int inx;
for (int i=0; i<[array count]; i++) {
if ([[[array objectAtIndex:i] allKeys] containsObject:#"val"]) {
inx=i;
break;
}
}
The method you are looking for is -[NSArray indexOfObjectPassingTest:]. You would use it like this:
NSUInteger i = [array indexOfObjectPassingTest:^(id obj, NSUInteger idx, BOOL *stop) {
return [[id objectForKey:#"val"] rangeOfString:#"1.5"].location != NSNotFound;
}];
If you just want to check that val starts with "1.5" you would use hasPrefix: instead.
Try this -
NSArray *valArray = [array valueForKey:#"val"];
int index = [valArray indexOfObject:#"1.5"];
Appended answer given by Mandeep, to show you the magic of key value coding ;)
NSUInteger idx = UINT_MAX;
NSCharacterSet* spaceSet = [NSCharacterSet whitespaceCharacterSet];
for(int i=0,i_l=[Yourarray count];i<i_l;i++) {
NSString* s_prime = [[Yourarray objectAtIndex:i] valueForKey:#"val"];
if ([s_prime length] < 4) {
continue;
}
NSString *subString = [[s_prime substringToIndex:4] stringByTrimmingCharactersInSet:spaceSet];
// NSLog(#"index %#",s);
if ([subString isEqualToString:secretNumber]){
idx = i;
break;
}
}
if (idx != UINT_MAX) {
// NSLog(#"Found at index: %d",idx);
} else {
// NSLog(#"Not found");
}

remove array entry with empty values

I have an array with a lot of empty values and I want to remove them from the array....
NSMutableArray *entry = [self.selectedRow allValues];
for (int i = 0 ; i < [entry count] ; i++) {
NSLog(#"count: %#", [entry objectAtIndex: i]);
NSLog(#"point: %#", [selectedRow valueForKey:[entry objectAtIndex:i]]);
if([[selectedRow valueForKey:[entry objectAtIndex: i]] length] < 2){
[selectedRow removeObjectAtIndex: i];
}
}
the < 2 is because there are some values there not really empty.....
for some reason [entry valueForKey:[entry objectAtIndex:i]]] is empty
and i get the exeption -[__NSCFDictionary removeObjectAtIndex:]: unrecognized selector sent to instance 0x7021510 but there is no dictionary involved ther are only arrays.
and when i count down for (int i = [entry count -1; i = 0; i--]){ the loop isn't even called?!?
I hope someone can help me with that....
EDIT:
Is not what initialy wanted but some how it works better that way...
I check the length for the valueForKey when I parse the file so i reduce the file size for more then the half and it works pretty good.....
Try this:
NSMutableArray *entry = [NSMutableArray arrayWithArray:[self.selectedRow allValues]];
because [self.selectedRow allValues] likely returns an NSArray you can't just pretend it's Mutable.
OH. and furthermore self.selectedRow looks like an NSDictionary. Try removeObjectForKey: instead.
Should be,
for (int i = [entry count] -1; i > 0; i--]){ }
And try,
for (int i = 0 ; i < [selectedRow count]; i++) {
if([[selectedRow objectAtIndex: i] count] < 2){
[selectedRow removeObjectAtIndex: i];
}
}