objective c - iOS comparing NSDictionary values -
i'm fetching 2 json
s , store them individually nsarray
, nsdictionary
.
this json
data structures looks like
( { cells = ( { valuename = "name"; text = "john appleseed"; }, { "option": { "text": "19" }, valuename = "age" }, etc... ) }, { cells = ( { valuename = "name"; text = "john appleseed"; }, { valuename = "age", "option": { "text": "19" } }, etc... ) } )
{ "map": { "first": "name", "second": "age" }, etc... }
the 2 has values needs cross referenced (as 1 contains data (alldata
), , other contains "map" (mapdata
) of data needed).
how may compare values of alldata
values of mapdata
while, if possible, keeping simplicity , memory in mind?
a great approach use containsobject
matching [alldata allvalues]
[mapdata allvalues]
, being given nsarray
object
of match. alas, not case. approach illustrates wish accomplish.
my initial approach slow, memory hogging , ugly (wrote memory):
nsarray *alldata = [nsjsonserialization jsonobjectwithdata:alldatajson options:kniloptions error:&jsonserializationerror]; nsdictionary *mapdata = [nsjsonserialization jsonobjectwithdata:mapdatajson options:kniloptions error:&jsonserializationerror]; nsmutabledictionary *resultdata = [[nsmutabledictionary alloc] init]; (int count = 0; count<alldata.count; count++) { id datavalue = [alldata objectatindex:count]; (id key in mapdata) { if ([[mapdata objectforkey:key] containsobject:datavalue]) { [resultdata setobject:[datavalue objectforkey:@"value"] forkey:key] } } }
it's important able reference each match of values match (as done in approach).
this not opinion based question optimisation , memory usage not opinion.
i found using data model memory efficient , pretty fast (clocked in @ average time of 0.001 sec alldata
's length of 1000 lines).
by extracting wanted values mapdata
, placing them in nsarray
values can matched values of alldata
.
when looping thru mapdataarray
secondary loop can created going thru alldata
's values. if mapdataarray containsobject
returns true, data can stored in momentary storage dictionary.
this allows easy management of data needed , can ignored. important momentary storage created inside of first loop (as you'll see in moment).
if , when values mapdataarray
found (by checking mapdataarray.count
momentarydata.count
) can break
current loop (thus saving time , memory).
it's easier @ code understand going on.
the data objects referenced in question.
nsarray *alldata = [nsjsonserialization jsonobjectwithdata:alldatajson options:kniloptions error:&jsonserializationerror]; nsdictionary *mapdata = [nsjsonserialization jsonobjectwithdata:mapdatajson options:kniloptions error:&jsonserializationerror];
creating mapdataarray
, looping thru it, creating momentary dictionary, appending found objects , appending momentary data resultdata
.
nsarray *mapdataarray = [[nsarray alloc] init]; mapdataarray = [[mapdataarray arraybyaddingobjectsfromarray:[[mapdata objectforkey:@"map"] objectforkey:@"first"]] arraybyaddingobjectsfromarray:[[mapdata objectforkey:@"map"] objectforkey:@"second"]]; mapdataarray = [[nsorderedset orderedsetwitharray:mapdataarray] array]; //remove duplicates nsmutabledictionary *resultdata = [[nsmutabledictionary alloc] init]; (int count = 0; count<alldata.count; count++) { nsmutabledictionary *momentarydata = [[nsmutabledictionary alloc] init]; int datanumber = count; nsarray *literal = [[alldata objectatindex:datanumber] objectforkey:@"cells"]; (int count = 0; count<literal.count; count++) { id literal = [[[alldata objectatindex:datanumber] objectforkey:@"cells"] objectatindex:count]; if ([mapdataarray containsobject:[literal objectforkey:@"valuename"]]) { id value = [literal objectforkey:@"text"]; if (!value) { value = [literal objectforkey:@"option"]; if (value && ![value isequal:[nsnull null]]) { value = [value objectforkey:@"text"]; } else { value = @""; } } [momentarydata setobject:[nsstring stringwithformat:@"%@", value] forkey:[literal objectforkey:@"valuename"]]; if (mapdataarray.count == momentarydata.count) { break; //we have came for... } } } [resultdata setobject:momentarydata forkey:[nsstring stringwithformat:@"%d", datanumber]]; }
Comments
Post a Comment