iOS NSArray Sorting - ios

I have a nested array and want to sort it by a key present inside the inner array.
below given is my array which I want to sort using NSSortDescriptor or in other way.
fares(
{
pid = 1;
type1 = (
{
color = "red";
size = "big";
properties = (
{
mod = "auto";
payment = "EMI";
moresegs = (
{
id = 141;
name = "abcd";
duration = "1 year"
})
})
});
type2 = (
{
color = "green";
size = "small";
properties = (
{
mod = "auto";
payment = "EMI";
moresegs = (
{
id = 141;
name = "abcd";
duration = "1 year"
})
})
})
}
{
pid = 1;
type1 = (
{
color = "red";
size = "big";
properties = (
{
mod = "auto";
payment = "EMI";
moresegs = (
{
id = 141;
name = "abcd";
duration = "1 year"
})
})
});
type2 = (
{
color = "green";
size = "big";
properties = (
{
mod = "auto";
payment = "EMI";
moresegs = (
{
id = 141;
name = "abcd";
duration = "1 year"
})
})
})
})
How can i sort above array using key "type2->properties->payment"?
-------update-----------
I modified the array and used NSSortDescriptor which solved my problem

Try this:
NSSortDescriptor *descriptor = [[NSSortDescriptor alloc] initWithKey:#"type1.size" ascending:YES];
NSArray *finalArray = [self.firstArray sortedArrayUsingDescriptors:[NSArray arrayWithObjects:descriptor,nil]];

Try this by inputing the fares array into this method-
+(NSArray*)sortedListBySize:(NSArray*)_unsortedList{
NSArray *sortedListBySize = [_unsortedList sortedArrayUsingComparator:(NSComparator)^(id obj1, id obj2){
if ([[obj1 valueForKeyPath:#"type2.properties.payments" ] intValue] < [[obj1 valueForKeyPath:#"type2.properties.payments"] intValue]) {
return NSOrderedAscending;
} else if ([[obj1 valueForKeyPath:#"type2.properties.payments" ] intValue] > [[obj1 valueForKeyPath:#"type2.properties.payments"] intValue]) {
return NSOrderedDescending;
}
return NSOrderedSame;
}];
return sortedListBySize;
}

Related

How to merge 2 Arrays by comparing two different objects having same values ?

I have 2 Arrays named "onGoingBookings" and "sortedMSArray" . I want to inject / merge sortedMSArray (status key only) to onGoingBooings Array (main Array) when both booking id values are same.
Response of OngoingBookings
{
addrLine1 = "Al Thanyah Fifth, Dubai, United Arab Emirates";
addrLine2 = " ";
amount = "";
apntDate = "2017-12-11";
apntDt = "2017-12-11 11:48:18";
apntTime = "11:48 am";
apptLat = "25.071571350098";
apptLong = "55.14294052124";
bid = 374;
bookType = 1;
cancelAmount = 30;
"cancel_reason" = "";
"cat_name" = "Car Wash";
"dispute_msg" = "";
disputed = "";
dt = 20171211114818;
email = "dev#ios.com";
fdata = {
};
fname = Apple;
lname = Mob;
notes = "";
pPic = "https://s3.amazonaws.com/iserve/ProfileImages/dev#ios.com2017-11-2711:34:26.jpg";
phone = 561462146;
pid = 48;
"star_rating" = 0;
statCode = 6;
status = "Job started.";
},
{
addrLine1 = "Al Thanyah Fifth, Dubai, United Arab Emirates";
addrLine2 = " ";
amount = "";
apntDate = "2017-12-06";
apntDt = "2017-12-06 19:29:14";
apntTime = "07:29 pm";
apptLat = "25.071369171143";
apptLong = "55.143840789795";
bid = 354;
bookType = 2;
cancelAmount = 50;
"cancel_reason" = "";
"cat_name" = Plumbing;
"dispute_msg" = "";
disputed = "";
dt = 20171206192914;
email = "";
fdata = {
};
fname = "";
lname = "";
notes = "";
pPic = "";
phone = "";
pid = "";
"star_rating" = 0;
statCode = 1;
status = "Job Pending";
},
{
addrLine1 = "Al Thanyah Fifth, Dubai, United Arab Emirates";
addrLine2 = " ";
amount = "";
apntDate = "2017-12-06";
apntDt = "2017-12-06 19:24:12";
apntTime = "07:24 pm";
apptLat = "25.071369171143";
apptLong = "55.143840789795";
bid = 353;
bookType = 1;
cancelAmount = 30;
"cancel_reason" = "";
"cat_name" = "Car Wash";
"dispute_msg" = "";
disputed = "";
dt = 20171206192412;
email = "";
fdata = {
};
fname = "";
lname = "";
notes = "";
pPic = "";
phone = "";
pid = "";
"star_rating" = 0;
statCode = 1;
status = "Job Pending";
},
Response of sortedMSArray
{
bookingid = 325;
status = 1;
},
{
bookingid = 333;
status = 3;
},
{
bookingid = 374;
status = 3;
}
I need Following Solution
Step 1 - compare both array by using #"bid"(ongoingbookings) and #"bookingid"(sortedMSArray)
Step 2 - merge the status key when both booking ids are same.
Please post a code snipped according to my code and response.
Reference Codes
if(requestType == RequestTypeGetAllApptDetails)
{
if(pageIndex == 0)
{
pastBookings = [[NSMutableArray alloc]init];
onGoingBookings = response[#"ongoing_appts"];
NSLog(#"CHECKINGFAST%#",onGoingBookings);
}
[pastBookings addObjectsFromArray:response[#"past_appts"]];
self.tableView.backgroundView = self.messageView;
[self.tableView reloadData];
}
else if(requestType == RequestTypeGetReportMaterialStatus)
{ // NSArray *custStatusTempArray = response;
customerStatusArray = response;
customerstatusDict = response[#"customerstatus"];
NSLog(#"CUSTOMERSTATUSARRAY %#", customerStatusArray);
NSLog(#"CUSTOMERSTATUSDICT %#", customerstatusDict);
if(customerStatusArray == nil || [customerStatusArray count]==0)
{
NSLog(#"NO MATERIAL ACCEPTED");
}
else
{
custStatusFilteredArray = [NSMutableArray array];
if([customerstatusDict isKindOfClass:[NSDictionary class]])
{
NSDictionary *dict = (NSDictionary *)customerstatusDict;
[dict enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) {
[custStatusFilteredArray addObject:obj];
NSLog(#"FILTEREDARRAY%#",custStatusFilteredArray);
}];
}
materialStatusStringArray = [custStatusFilteredArray copy];
NSLog(#"materialStatusStringarray%#",materialStatusStringArray);
//sorting the materialstatus string array
NSSortDescriptor* sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:#"bookingid" ascending:NO];
sortedMSArray = [materialStatusStringArray sortedArrayUsingDescriptors:#[sortDescriptor]];
NSLog(#"Sorted Array Response -%#", sortedMSArray);

I am filtering a multilevel NSArray using NSPredicate., i am trying to filter 3rd child of array using predicate but i am getting this

Unable to parse the format string "json.option_titles.ANY.options.ANY.jobID == %#
Although i can use the for loop but i might have option titles length long so it will be not good. will it be possible using nspredicate?
This is my sample Data
(
{
dept = 1194;
id = 2299;
job = 22048;
json = {
name = tester;
"option_titles" = (
{
"custom_option_title" = "";
"financing_option" = "";
options = (
{
hours = "2.00";
jobID = 22048;
optionDesc = "Sample Description";
},
{
hours = "2.00";
jobID = 22048;
optionDesc = "Sample Description";
},
);
}
);
"system_observations" = "";
};
name = tester;
"sort_order" = 178;
"system_observations" = "";
},
{
dept = 1195;
id = 2300;
job = 22000;
json = {
name = tester second;
"option_titles" = (
{
"custom_option_title" = "title option";
"financing_option" = "";
options = (
{
hours = "2.00";
jobID = 22000;
optionDesc = "Sample Description";
},
{
hours = "2.00";
jobID = 22000;
optionDesc = "Sample Description";
},
);
}
);
"system_observations" = "";
};
name = tester;
"sort_order" = 179;
"system_observations" = "";
}
)
Tried Code:-
NSArray *allJobs = [self getAllJobs];
allJobs = [allJobs filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"(dept_id == %#)",deptId]];
NSMutableArray *coumpoArray = [NSMutableArray new];
for (NSDictionary *job in allJobs) {
NSPredicate *predicateDeepFilterJobID = [NSPredicate predicateWithFormat:#"json.option_titles.options.jobID == %#",job[#"id" ]];
[coumpoArray addObject:predicateDeepFilterJobID];
}
NSPredicate *pr = [NSCompoundPredicate orPredicateWithSubpredicates:coumpoArray];
filterBydept = [arrayTemplate filteredArrayUsingPredicate:pr];
Tried another predicate:-
NSArray *allJobs = [self getAllJobs];
allJobs = [allJobs filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"(dept_id == %#)",deptId]];
NSMutableArray *coumpoArray = [NSMutableArray new];
for (NSDictionary *job in allJobs) {
NSPredicate *predicateDeepFilterJobID = [NSPredicate predicateWithFormat:#"json.option_titles.ANY.options.ANY.jobID == %#",job[#"id" ]];
[coumpoArray addObject:predicateDeepFilterJobID];
}
NSPredicate *pr = [NSCompoundPredicate orPredicateWithSubpredicates:coumpoArray];
filterBydept = [arrayTemplate filteredArrayUsingPredicate:pr];

Filter NSMutableArray with All the values of nsarray

I have MutableArray like this...
restaurants = ({
cuisines = ({
"cuisine_id" = 1;
"cuisine_name" = Indian;
},
{
"cuisine_id" = 2;
"cuisine_name" = SriLanka;
}
);}
{ cuisines = ({
"cuisine_id" = 1;
"cuisine_name" = Chinese;
},
{
"cuisine_id" = 2;
"cuisine_name" = Afghani;
}
);}
{cuisines =({
"cuisine_id" = 1;
"cuisine_name" = Chinese;
},
{
"cuisine_id" = 2;
"cuisine_name" = Afghani;
}
);}
)
And I'm Filtering Restaurants Array With multiple values of cuisine_name
For Example if I have a,
Nsarray like this cuisine_name (
Indian,
Srilankan,
Chinese,
)
I want to filter my Restaurants array on basis of each object of cusine_name.
At present I'm doing like this..
NSPredicate *predicateCuisines = [NSPredicate predicateWithFormat:#"(cuisines.cuisine_name = %#)",[cuisineTypes valueForKey:#"cuisine_name"]];
[self.arrRestaurantList filterUsingPredicate:predicateCuisines];
But it filtering Using description...For Restaurant Array which contains whole three values(Indian,Srilankan,Chinese) but i want to filter with each object of cuisine_name.
Any help will really appreciated..
plz use this
NSArray* arrtu4 = #[#{#"cuisines" : #[#{#"cuisine_id" : #1,#"cuisine_name" : #"Indian"},#{ #"cuisine_id" : #2, #"cuisine_name" : #"SriLanka"}]},#{ #"cuisines" : #[#{#"cuisine_id" : #1,#"cuisine_name" : #"Chinese"},#{#"cuisine_id" : #2,#"cuisine_name" : #"Afghani"}]},#{#"cuisines" :#[#{#"cuisine_id" :#1,#"cuisine_name" : #"Chinese"},#{ #"cuisine_id" : #2,#"cuisine_name" : #"Afghani"}]}];
NSMutableArray *arrryfilted = [NSMutableArray array];
NSArray *arrayCountrys = #[#"Chinese",#"SriLanka",#"Indian"];
for (int i = 0; i<arrtu4.count; i++)
{
NSArray *filterArray2 = [[arrtu4 objectAtIndex:i]valueForKey:#"cuisines"];
NSArray *filterArray3 = [filterArray2 filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id _Nonnull evaluatedObject, NSDictionary<NSString *,id> * _Nullable bindings) {
return [arrayCountrys containsObject:[evaluatedObject valueForKey:#"cuisine_name"]] ;
}]];
[arrryfilted addObjectsFromArray:filterArray3 ];
}
NSLog(#"%#",arrryfilted);
output:
2016-08-20 16:44:59.856 coredataReltaion[6762:152672] (
{
"cuisine_id" = 1;
"cuisine_name" = Indian;
},
{
"cuisine_id" = 2;
"cuisine_name" = SriLanka;
},
{
"cuisine_id" = 1;
"cuisine_name" = Chinese;
},
{
"cuisine_id" = 1;
"cuisine_name" = Chinese;
}
)

How to create a sub NSArray that includes key-value pairs?

I have the following NsArray and I want to sort it and create a sub array that include specific key-value pairs.
{
scores = (
{
category = 2;
"league_code" = epl;
"team_away" = Everton;
"team_home" = Liverpool;
},
{
category = 2;
"league_code" = epl;
"team_away" = Fulham;
"team_home" = "Swansea City";
},
{
category = 3;
"league_code" = ita;
"team_away" = Torino;
"team_home" = Milan;
},
{
category = 3;
"league_code" = ita;
"team_away" = Lazio;
"team_home" = Juve;
}
}
}
and I would like to create a new array or just modify array to include only objects with "league_code" = epl key.
So I want to get
{
scores = (
{
category = 2;
"league_code" = epl;
"team_away" = Everton;
"team_home" = Liverpool;
},
{
category = 2;
"league_code" = epl;
"team_away" = Fulham;
"team_home" = "Swansea City";
}
}
}
I tried to convert it to use dictionaryWithObjects:forKeys but it didn't work.
NSMutableArray* newArray = [NSMutableArray array];
NSArray* oldArray = outerDictionary[#"scores"];
for (NSDictionary* dictEntry in oldArray) {
NSString* leagueCode = dictEntry[#"league_code"];
if ([leagueCode isEqualToString #"epl"]) {
[newArray addObject:dictEntry];
}
}
Was that all that hard?
Loop Through and the if it matches your conditions add it to a dictionary. I recommend the for-loop but any loop while do.

Issue with Sorting NSMutableArray

I have an NSMutableArray which contains an NSDictionary, I need to sort the array based on certain criteria.
Sorting criteria is
sort based on properties.property.value, suppose if I want to sort based on properties.property.name = Risk value. I want all the elements with Risk value first with the value in Ascending order. That means for the Dictionary which doesn't have
properties.property.name = Risk must come last. Some of the dictionaries don't have these names.
Please help...
finalArr (
{
ViewTag = 101;
"action-taken-date" = {
class = "java.util.GregorianCalendar";
text = "2013-06-03 22:23:28.0 PDT";
};
alarms = 0;
alerts = 0;
application = {
assignee = "Test Name";
completed = false;
"properties" = {
class = "java.util.ArrayList";
property = (
{
label = Risk;
name = Risk;
value = "3 - Low";
},
{
label = "Start Time";
name = "Start Time";
value = "05/09/13 06:00:00";
}
);
};
{
ViewTag = 102;
"date" = {
class = "java.util.GregorianCalendar";
text = "2013-06-03 22:23:28.0 PDT";
};
alarms = 0;
alerts = 0;
application = {
assignee = "Test Name";
completed = false;
"properties" = {
class = "java.util.ArrayList";
property = (
{
label = Risk;
name = Risk;
value = "2 - Low";
},
{
label = "Start Time";
name = "Start Time";
value = "05/09/13 06:00:00";
}
);
};
{
ViewTag = 103;
"date" = {
class = "java.util.GregorianCalendar";
text = "2013-06-03 22:23:28.0 PDT";
};
alarms = 0;
alerts = 0;
application = {
assignee = "Test Name";
completed = false;
"properties" = {
class = "java.util.ArrayList";
property = (
{
label = Status;
name = Status;
value = "Pending Signoffs";
},
{
label = Priority;
name = Priority;
value = 3;
}
);
};
{
ViewTag = 104;
"date" = {
class = "java.util.GregorianCalendar";
text = "2013-06-03 22:23:28.0 PDT";
};
alarms = 0;
alerts = 0;
application = {
assignee = "Test Name";
completed = false;
"properties" = {
property = (
{
label = Priority;
name = priority;
value = 1;
},
{
label = "Start Time";
name = "Start Time";
value = "05/09/13 06:00:00";
}
);
};
{
ViewTag = 103;
"date" = {
class = "java.util.GregorianCalendar";
text = "2013-06-03 22:23:28.0 PDT";
};
alarms = 0;
alerts = 0;
application = {
assignee = "Test Name";
completed = false;
"properties" = {
property = (
{
label = Status;
name = Status;
value = "Pending Signoffs";
},
{
label = Priority;
name = Priority;
value = 2;
}
);
};
)
Try with this
NSString *risk = #"Risk";
[finalArray sortUsingComparator:^NSComparisonResult(NSDictionary * dict1, NSDictionary * dict2) {
NSDictionary *property1 = dict1[#"properties"][#"property"][0];
NSString *name1 = property1[#"name"];
NSDictionary *property2 = dict2[#"properties"][#"property"][0];
NSString *name2 = property2[#"name"];
if ([name1 isEqualToString:name2]) {
//if both names are equal then they are sorted based on value
NSString *value1 = property1[#"value"];
NSString *value2 = property2[#"value"];
return [value1 compare:value2 options:NSNumericSearch];
}else if ([name1 isEqualToString:risk]){
//if name1 is equal to risk it is moved up
return NSOrderedAscending;
}else{
return NSOrderedDescending;
}
}];
It sounds like you have multiple different requirements (logic) which go into determining the desired sort result. You should write your own comparison logic and use one of the array methods like sortUsingComparator:.

Resources