How to efficiently loop through multiple nested NSDictionaries and compare values? - objective-c

I have the following structure in an NSDictionary that I got after parsing the XMl using XMl reader from here http://troybrant.net/blog/2010/09/simple-xml-to-nsdictionary-converter/:
{
Document = {
Page = (
{
TextLR = {
Line = {
LineProps = {
applyBreakingRules = true;
autoDecimalTabPos = 0;
breakJust = BreakOptimal;
direction = ES;
hyphenationZone = 0;
kindAlign = Left;
kindJust = FullInterWord;
left = 0;
presSuppressWiggle = true;
rightBreak = 0;
rightJustify = 0;
text = "\n\t\n\t\t\n\t\t\t\n\t\t\t\t";
treatHyphenAsRegular = true;
};
Text = {
text = "\n\t\t\t\tHello ";
};
betweenBottom = false;
betweenTop = false;
bottomEnable = false;
break = EndPara;
cpLim = 12;
cpStart = 0;
direction = ES;
doc = Main;
firstLineCp = true;
};
bottom = 114115;
cpLim = 12;
cpStart = 0;
doc = Main;
left = 0;
right = 2438349;
text = "\n\t\t";
top = 0;
};
cpLim = 81963072;
fBuggyJust = false;
fEmptyPage = false;
fHasBubbles = false;
fSlicedPage = false;
height = 3448422;
marginBottom = 3448422;
},
{
TextLR = {
Line = {
LineProps = {
applyBreakingRules = true;
autoDecimalTabPos = 0;
breakJust = BreakOptimal;
direction = ES;
hyphenationZone = 0;
kindAlign = Left;
kindJust = FullInterWord;
left = 0;
presSuppressWiggle = true;
rightBreak = 0;
rightJustify = 0;
text = "\n\t\n\t\t\n\t\t\t\n\t\t\t\t";
treatHyphenAsRegular = true;
};
Text = {
text = "\n\t\t\t\tHello SO ";
};
betweenBottom = false;
betweenTop = false;
bottomEnable = false;
break = EndPara;
cpLim = 12;
cpStart = 0;
direction = ES;
doc = Main;
firstLineCp = true;
};
bottom = 114115;
cpLim = 12;
cpStart = 0;
doc = Main;
left = 0;
right = 2438349;
text = "\n\t\t";
top = 0;
};
cpLim = 81963072;
fBuggyJust = false;
fEmptyPage = false;
fHasBubbles = false;
fSlicedPage = false;
height = 3448422;
marginBottom = 3448422;
}
);
doc = "simple1.htm";
xdpi = 72;
xmlns = "http://apple/sites;
"xmlns:xsi" = "http://www.w3.org/2001/XMLSchema-instance";
"xsi:schemaLocation" = "xmlns = "http://apple/sites/Dump.xsd";
ydpi = 72;
};
}
I have been struggling to iterate through this nested NSDictionary and extract each attribute to compare with another NSDictionary of similar structure. The dictionaries can be somewhat dynamic, as in there might be additional levels of nesting for different xml files but the dictionaries to compare are of exact similar structure with same tags. Is there a way to iterate and create nested dictionaries on the go and then have parallel loops going so that I can extract the values and compare with between 2 NSDictionaries? I have tried the following code, but I am stuck in finding a good way to make it create dictionaries dynamically at the same time compare values/attributes with another dictionary. Help is much appreciated.
NSArray *arrPages = [[_xmlDictionary_master objectForKey:#"Document"] objectForKey:#"Page"];//this would return the array of Page dictionaries
for(int i=0;i<[arrPages count];i++){
NSDictionary *aPage = [arrStation objectAtIndex:i];
NSLog(#"id = %#",[aStation objectForKey:#"id"]);
}
Above code returns 2 Nested key/value pairs which in turn have multiple nested dictionaries. I am finding it hard to know which value has nesting and which doesnt during run time.

First tip: Refactor your data so that this isn't such a difficult operation! If that's not possible there's a few things you can try.
Rather than a "for loop", use:
[arrStation enumerateObjectsWithOptions: NSEnumerationConcurrent
usingBlock: ^(NSDictionary *aPage, NSUInteger idx, BOOL *stop) {
// Code here for compare
}];
That may perform your operations in parallel.
Another technique is using GCD. Using a dispatch_async, then a dispatch_apply can achieve something very similar.
dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
dispatch_apply([arrStation count], dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(size_t idx) {
// Work here
});
});
Spend some time reading through the Concurrency Programming Guide. It's a great way to understand what options are available and how they work.

Related

Loop over path points in Photoshop

I'm trying to iterate over a create path in Photoshop finding out the anchor points position etc
var srcDoc = app.activeDocument;
// create the array of PathPointInfo objects
var lineArray = new Array();
lineArray.push(new PathPointInfo());
lineArray[0].kind = PointKind.CORNERPOINT;
lineArray[0].anchor = new Array(20, 160);
lineArray[0].leftDirection = [35, 200];
lineArray[0].rightDirection = lineArray[0].anchor;
lineArray.push(new PathPointInfo());
lineArray[1].kind = PointKind.CORNERPOINT;
lineArray[1].anchor = new Array(20, 40);
lineArray[1].leftDirection = lineArray[1].anchor;
lineArray[1].rightDirection = [220, 260];
// create a SubPathInfo object, which holds the line array in its entireSubPath property.
var lineSubPathArray = new Array();
lineSubPathArray.push(new SubPathInfo());
lineSubPathArray[0].operation = ShapeOperation.SHAPEXOR;
lineSubPathArray[0].closed = false;
lineSubPathArray[0].entireSubPath = lineArray;
//create the path item, passing subpath to add method
var myPathItem = srcDoc.pathItems.add("A Line", lineSubPathArray);
for (var i = 0; i < lineSubPathArray[0].entireSubPath.length; i++)
{
var b = lineSubPathArray[0].entireSubPath[i].anchor;
alert(b);
}
This works fine, but instead of creating the path and finding out it's information I want to loop over each path and get the same. This should be the same as the loop above only without explicitly calling lineSubPathArray and its parts.
for (var i = 0; i < srcDoc.pathItems[0].subPathItems.pathPoints.length; i++) // wrong I think
{
var b = srcDoc.pathItems[0].entireSubPath[i].anchor; // wrong
alert(b);
}
Almost: you need to iterate through subPathItems which consist of pathPoints:
var srcDoc = activeDocument;
var workPath = srcDoc.pathItems[0];
var i, k, b;
for (i = 0; i < workPath.subPathItems.length; i++) {
for (k = 0; k < workPath.subPathItems[i].pathPoints.length; k++) {
b = workPath.subPathItems[i].pathPoints[k].anchor;
alert(b);
}
}

Get the "id" of the TD Node

I'm trying to get the "id" of the TD Node that a field is in. I created a function, but I am not getting the data out of the loop ... I'm guessing that the variables are out of scope and I can't figure out how to make it work.
function getTD(vStartNm)
{
vNm = document.getElementsByName(vStartNm),
vId = vNm[0].getAttribute('id'),
vNode = document.getElementById(vId),
vTag = vNode.nodeName;
vTDId = '';
for (i = 0; i >10; i++)
{
vPar = vNode.parentNode;
vTag = vPar.nodeName;
vTDId = vPar.id;
vNode = vPar;
if (vTag == 'TD'){return vTDId; break;}
}
}
vTD_id = getTD('udfchar45');
vTD = document.getElementById(vTD_id);
my syntax on the do loop may be wrong. once i changed it to a while loop, it seems to work just fine.
function getTD(vStartNm)
{
vNm = document.getElementsByName(vStartNm),
vId = vNm[0].getAttribute('id'),
vNode = document.getElementById(vId),
vTag = vNode.nodeName;
vTDId = '';
i=0;
while (i < 10)
{
i++;
vPar = vNode.parentNode;
vTag = vPar.nodeName;
vTDId = vPar.id;
vNode = vPar;
if (vTag == 'TD'){return vTDId; break;}
}
}
vTD_id = getTD('udfchar45');
vTD = document.getElementById(vTD_id);

Zedgraph - Change X-Axis from points to frequency

i have a working program where i can add an array to a Zedgraph and show this in a form.
Now i only want to change the display of the x-axis from points (0..400) to frequency (9e3..6e9 Hz).
Here are my currently working functions:
public void AddGraph(double[] Values, string LegendName)
{
int i = 0;
PointPairList list = new PointPairList();
for (i = 0; i < Values.Length; i++)
{
list.Add(i, Values[i]);
}
if (i > MaxXAxis)
MaxXAxis = i;
SList.Add(list);
SListColor.Add(Color.Black);
}
SListName.Add(LegendName);
}
public void ShowDiagram(string Title, string XAxisName, string YAxisName,
int Timeout_ms)
{
ZedGraph.ZedGraphControl zgc = new ZedGraphControl();
GraphPane myPane = zgc.GraphPane;
LineItem myCurve = null;
// Set the titles and axis labels
myPane.Title.Text = Title;
myPane.XAxis.Title.Text = XAxisName;
myPane.YAxis.Title.Text = YAxisName;
for (int i = 0; i < SList.Count(); i++)
{
myCurve = myPane.AddCurve(SListName[i], SList[i], SListColor[i],
SymbolType.None);
myCurve.Line.Width = 2;
}
// Add gridlines to the plot, and make them gray
myPane.XAxis.MinorGrid.IsVisible = true;
myPane.YAxis.MinorGrid.IsVisible = true;
myPane.XAxis.MinorGrid.Color = Color.LightGray;
myPane.YAxis.MinorGrid.Color = Color.LightGray;
myPane.XAxis.MinorGrid.DashOff = 0;
myPane.YAxis.MinorGrid.DashOff = 0;
myPane.XAxis.MajorGrid.IsVisible = true;
myPane.YAxis.MajorGrid.IsVisible = true;
myPane.XAxis.MajorGrid.Color = Color.Gray;
myPane.YAxis.MajorGrid.Color = Color.Gray;
myPane.XAxis.MajorGrid.DashOff = 0;
myPane.YAxis.MajorGrid.DashOff = 0;
// Move Legend to bottom
myPane.Legend.Position = LegendPos.Bottom;
zgc.AxisChange();
myPane.XAxis.Scale.Max = MaxXAxis;
zgc.Location = new Point(0, 0);
zgc.Size = new Size(panel_diagramm.ClientRectangle.Width, panel_diagramm.ClientRectangle.Height);
panel_diagramm.Controls.Add(zgc);
}
How can i change the above two functions that they display the frequency in the x-axis?
I already tried to change the AddGraph-function to pass the needed parameters and to calculate the list to have the correct values. But what then...?
public void AddGraph_Frequency(int **Points**, double **StartFrequency**,
double **StopFrequency**, double[] Values, string GraphColor, string LegendName)
{
...
double frequency = StartFrequency; //der erste Punkt
double Intervall = (StopFrequency - StartFrequency) / Points;
for (i = 0; i < Points; i++)
{
list.Add(frequency, Values[i]);
frequency = frequency + Intervall;
}
....
}
Thanks for any help
best regards
Solved.
Missing was:
myPane.XAxis.Scale.Max = Stopfrequency;
myPane.XAxis.Scale.Min = Startfrequency;

Circular Gauge Gradient - TeeChart - MonoAndroid

I am using TreeChart to make an indicator as shown in the picture. But I have a problem I can not make the three-color gradient to that gauge. This is my code
Steema.TeeChart.TChart tChart = new Steema.TeeChart.TChart(this);
tChart.Panel.Transparent = false;
Steema.TeeChart.Styles.Gauges gauges = new Steema.TeeChart.Styles.Gauges(tChart.Chart);
Steema.TeeChart.Drawing.Gradient g = new Steema.TeeChart.Drawing.Gradient(gauges.Chart);
gauges.bBrush.Gradient.Direction = Steema.TeeChart.Drawing.GradientDirection.DiagonalUp;
gauges.bBrush.Gradient.StartColor = System.Drawing.Color.Red;
gauges.bBrush.Gradient.MiddleColor = System.Drawing.Color.Black;
gauges.bBrush.Gradient.EndColor = System.Drawing.Color.Blue;
gauges.bBrush.Gradient.Visible = true;
gauges.Pen.Color = System.Drawing.Color.FromArgb(5,56,73);
gauges.TotalAngle = 180; // circular arc
gauges.RotationAngle = 180; // arc rotation angle
gauges.HandStyle = Steema.TeeChart.Styles.HandStyle.Triangle; // pointer style
gauges.Center.Style = Steema.TeeChart.Styles.PointerStyles.Circle; // SPHERE center circle style
gauges.Center.HorizSize = 5; // center circle level size
gauges.Center.VertSize = 5; // center circle vertical size
gauges.ShowInLegend = false; // display the legend
gauges.HandDistance = 23; // pointer length
//---------------------------------------------------
gauges.Value = 80;
gauges.Minimum = 0; // minimum;
gauges.Maximum = 100; // maximum value
//----------------------------------------------------
gauges.MinorTickDistance = 0;
gauges.Pen.DashWidth = 23;
gauges.Chart.Axes.Left.AxisPen.Width = 65; // brush width;
gauges.Chart.Axes.Left.AxisPen.Color = System.Drawing.Color.Red;
gauges.Chart.Axes.Left.MinorTickCount = 5; // the scale value scale line number
gauges.Chart.Axes.Left.MinorTicks.Length = 10; // the scale value scale line length of
gauges.Chart.Axes.Left.Ticks.Length = 20; // display the value scale line length of
gauges.Chart.Axes.Left.Increment = 3000; // the scale value of interval size
SetContentView(tChart) ;
I also tried the following lines of code
gauges.CircleGradient.Direction = Steema.TeeChart.Drawing.GradientDirection.DiagonalUp;
gauges.CircleGradient.Visible = true;
gauges.CircleGradient.StartColor = System.Drawing.Color.Green;
gauges.CircleGradient.EndColor = System.Drawing.Color.Red;
gauges.CircleGradient.UseStandardGradient = true;
I hope I help
regards
You should use Steema.TeeChart.Styles.CircularGauge instead of Steema.TeeChart.Styles.Gauges which is a much simpler gauge version. For example, using the code snippet below, you get a similar gauge to the image in your link:
Is this similar to what you are looking for?
tChart1.Header.Visible = false;
Steema.TeeChart.Styles.CircularGauge circularGauge1 = new Steema.TeeChart.Styles.CircularGauge(tChart1.Chart);
circularGauge1.Frame.Visible = false;
circularGauge1.FaceBrush.Visible = false;
circularGauge1.DisplayTotalAngle = 180;
circularGauge1.TotalAngle = 180;
circularGauge1.Value = 200;
circularGauge1.Ticks.Visible = false;
circularGauge1.Minimum = 0;
circularGauge1.Maximum = 1000;
circularGauge1.Axis.AxisPen.Visible = false;
circularGauge1.Axis.Increment = 500;
circularGauge1.RedLine.Visible = false;
circularGauge1.GreenLineStartValue = 0;
circularGauge1.GreenLineEndValue = 1000;
circularGauge1.GreenLine.Gradient.Direction = Steema.TeeChart.Drawing.GradientDirection.LeftRight;
circularGauge1.GreenLine.Gradient.UseMiddle = true;
circularGauge1.GreenLine.Gradient.StartColor = Color.Orange;
circularGauge1.GreenLine.Gradient.MiddleColor = Color.Yellow;
circularGauge1.GreenLine.Gradient.EndColor = Color.Green;
circularGauge1.GreenLine.Pen.Visible = false;

Accessing a Key in JSON Response

How in the following JSON response can I check if uids is nil ?
{
height = 480;
pid = "F#dd705e6b96a6e894556c0db84870501e_d97383cc80238c38b8907d99690fa1c9";
tags = (
{
attributes = {
glasses = {
confidence = 97;
value = false;
};
smiling = {
confidence = 97;
value = false;
};
};
center = {
x = "60.83";
y = "75.21";
};
gid = "<null>";
height = "49.58";
label = "";
manual = 0;
nose = {
x = "76.21";
y = "77.16";
};
pitch = "-5.55";
recognizable = 0;
roll = "-0.45";
uids = ( // <<<<<========== UIDs Key
);
width = "66.11";
yaw = "-19.56";
}
);
url = "http://face.com/images/ph/a6e529853432599dad6da996746cb070.jpg";
width = 360;
}
When I try :
if ([[[[photo objectForKey:#"tags"] objectAtIndex:0] valueForKey:#"uids"] count] == 0)
It keeps returning FALSE all the time.
I'm able to access a lot of these keys successfully. But it's just this one key that's giving me issues.
Like, to access the url key, I am using :
[photo objectForKey:#"url"];
And it's working absolutely fine.
What am I doing wrong with the uids key ?