# Using sort functions in collections

• ### Question

• Hi, I'm a little bit stuck on how to apply the sort functions in my code, it could be that i've gone down the wron path. My code looks like this:

double uppermost = (myCanvas.ActualHeight - height) / 2;

SortedDictionary<double, double> openings = new SortedDictionary<double, double>();

var sortedList2 = openings.OrderBy(p => p.Key);

double NumberOfZones = 1;
foreach (KeyValuePair<double, double> p in openings)
{
double ZoneLength = 300; //first zone should take lowest openings key and add it to zero, last should take highest openings key+value and subtract it from length, others should subtract previous key+value from key

if (p.Key > 0)
{ NumberOfZones += 1; }
if (NumberOfZones == 1)
{ dist = length; }
for (double z = 0, leftermost = (myCanvas.ActualWidth - length) / 2; z < NumberOfZones; z++, leftermost = (myCanvas.ActualWidth - length) / 2 + p.Key + p.Value)//Math.Ceiling((myCanvas.ActualWidth - length) / 2 + p.Key + p.Value) / (centres / 10)
{
double StudCount = Math.Ceiling(ZoneLength / (centres / 10));

for (double i = 0; i < StudCount; ++i, leftermost += (centres / 10))
{
Line LX = new Line();
LX.Y1 = uppermost;
LX.Y2 = LX.Y1 + height;
LX.X1 = leftermost;
LX.X2 = LX.X1;
LX.Style = style;
}
}
}

As commented out in the ZoneLength variable, which i've hard coded at this point, I'm looking to have it reference my sorted dictionary such that the lowest sorted value stays as is, the highest adds the associated value and then all is subtracted from my outside variable length, and the values in between subtract the lower sorted key together with it's associated value. Any help would be appreciated, i'm so close to the finish on this app!

Thanks,

Matthew

Saturday, January 19, 2019 1:43 PM

• Things like First, Last, and Previous might be causing trouble because you're in the middle of iterating through the container.  It already has a position.

Although it seems less elegant, you might need to consider making a copy of the keys into a simple array, then iterate through the array using a (for i = 0; i < keys.Length(), i++ ).  That way, it's much easier to refer to the first and last element, and one you have "i", you can find the previous element by using openings[keys[i-1]].

Tim Roberts | Driver MVP Emeritus | Providenza &amp; Boekelheide, Inc.

Sunday, January 20, 2019 7:39 PM
• Hi matty1248,

I am not sure what you want to do for x. Hence I just fix the code for your reference.

``` int O1 = 100;
int O2 = 50;
int O3 = 000;
int O4 = 150;

SortedDictionary<string, int> openings = new SortedDictionary<string, int>();

int NumberOfZones = 1;

List<string> key = new List<string>();
foreach (var item in openings)
{
}
foreach (KeyValuePair<string, int> p in openings)
{
if (p.Value > 0)
{ NumberOfZones += 1; }

for (int i = 1; i <= key.Count; i++)
{
int x = openings[key[i]] - openings[key[i - 1]];
}
}```

Best Regards,

Wendy

MSDN Community Support
Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

• Marked as answer by Thursday, January 31, 2019 10:02 PM
Thursday, January 31, 2019 10:01 AM

### All replies

• I can't quite follow your description, but openings.Keys().First() should return the smallest key, and openings.Keys().Last() should return the largest key.  Is that enough to let you write your loop?

Tim Roberts | Driver MVP Emeritus | Providenza &amp; Boekelheide, Inc.

Saturday, January 19, 2019 11:23 PM
• Hi Tim,

thanks for your response, I think I was oversimplifying this issue. This openings.Keys().First()/last() syntax must feature I think, but i think i also need something like Previous() for in between instances, or otherwise to somehow say openings.Keys(-1) to refer to the previous key. My code has changed quite radically now, not sure if it's much use to show, here it is:

public void Multi()
{
if (!double.TryParse(TextBox1O1.Text, out double width)||!double.TryParse(TextBox3O1.Text, out double dist)||
//!double.TryParse(TextBox1O2.Text, out double width2)||!double.TryParse(TextBox3O2.Text, out double dist2)||
!double.TryParse(TextBox1.Text, out double length)||!double.TryParse(TextBox2.Text, out double height)||
!double.TryParse(TextBox3.Text, out double centres))
{
return;
}
myCanvas.Children.Clear();
double uppermost = (myCanvas.ActualHeight - height) / 2;

SortedDictionary<double, double> openings = new SortedDictionary<double, double>();

double NumberOfZones = 1;

foreach (KeyValuePair<double, double> p in openings)
{
if (p.Key > 0)
{ NumberOfZones += 1; }

double leftermostA = (myCanvas.ActualWidth - length) / 2;
double leftermostBC = (myCanvas.ActualWidth - length) / 2 + p.Key + p.Value + Math.Ceiling(p.Key + p.Value / (centres / 10));

double ZoneLengthA;
if (NumberOfZones == 1) {ZoneLengthA = length; }
else {ZoneLengthA = openings.Keys.First(); }        //openings[dist]; - dk why this doesnt work

//double ZoneLengthB;
//if (NumberOfZones > 2) { ZoneLengthB = length - (openings.Keys.Previous() + openings.Values.Previous()); }
//else { ZoneLengthB = 0; }

double ZoneLengthC;
if (NumberOfZones > 1) { ZoneLengthC = length - (openings.Keys.Last() + openings.Values.Last()); }
else {ZoneLengthC = 0; }

{
double StudCount = Math.Ceiling(ZoneLengthA / (centres / 10));

for (double i = 0; i < StudCount; ++i, leftermostA += (centres / 10))
{
Line LX = new Line();
LX.Y1 = uppermost;
LX.Y2 = LX.Y1 + height;
LX.X1 = leftermostA;
LX.X2 = LX.X1;
LX.Style = style;
}
}

//for (double z = 0; z < NumberOfZones; z++, leftermostBC)
//{
//    double StudCount = Math.Floor(ZoneLengthB / (centres / 10));

//    for (double i = 0; i < StudCount; ++i, leftermostBC += (centres / 10))
//    {
//        Line LX = new Line();
//        LX.Y1 = uppermost;
//        LX.Y2 = LX.Y1 + height;
//        LX.X1 = leftermostBC;
//        LX.X2 = LX.X1;
//        LX.Style = style;
//    }
//}

{
double StudCount = Math.Floor(ZoneLengthC / (centres / 10));

for (double i = 0; i < StudCount; ++i, leftermostBC += (centres / 10))
{
Line LX = new Line();
LX.Y1 = uppermost;
LX.Y2 = LX.Y1 + height;
LX.X1 = leftermostBC;
LX.X2 = LX.X1;
LX.Style = style;
}
}
}

Again, any help would be appreciated, just can't seem to find that syntax.

Thanks,

Matthew

• Edited by Sunday, January 20, 2019 2:08 PM
Sunday, January 20, 2019 9:03 AM
• Things like First, Last, and Previous might be causing trouble because you're in the middle of iterating through the container.  It already has a position.

Although it seems less elegant, you might need to consider making a copy of the keys into a simple array, then iterate through the array using a (for i = 0; i < keys.Length(), i++ ).  That way, it's much easier to refer to the first and last element, and one you have "i", you can find the previous element by using openings[keys[i-1]].

Tim Roberts | Driver MVP Emeritus | Providenza &amp; Boekelheide, Inc.

Sunday, January 20, 2019 7:39 PM
• Thanks Tim, I was thinking i should do something like this, I've been playing around with this loop all day and if i keep these values within the loop they get duplicated in my output. I thought there must be something like this i-1 componant as well, i think these two implementations should solve all the issue's. I'll try to implement all this tomorrow then I'll close this off, thanks for your help.
Sunday, January 20, 2019 9:35 PM
• I jut can't quite get it to work :( , it's really frustrating. when i try to implement it in my sorteddictionary i get a squigly under 'openings.Keys[i - 1]':

SortedDictionary<double, double> openings = new SortedDictionary<double, double>();

double NumberOfZones = 1;
for (int i = 2; i < openings.Count; i++)
{
if (p.Key > 0) { NumberOfZones += 1; }
if (NumberOfZones > 1) { ZoneLength = length; }
else { ZoneLength = openings.First().Key - openings.First().Value; };
if (NumberOfZones > 1) { ZoneLength = length - openings.Last().Key; }
else { ZoneLength = 0; }
if (NumberOfZones > 2) { ZoneLength = openings.Keys - openings.Keys[i - 1]; }
else { ZoneLength = 0; }
var x = openings[i - 1];
}

When i try to implement it within a list it does squigly's under the bits in bold:

List<OpeningObj> openings = new List<OpeningObj>();
openings.Add(new OpeningObj() { widthA = width, distanceA = dist});
openings.Add(new OpeningObj() { widthA = width2, distanceA = dist2});
openings.Add(new OpeningObj() { widthA = width3, distanceA = dist3});
openings.Add(new OpeningObj() { widthA = width4, distanceA = dist4});
var sortedList = openings.OrderBy(t => t.distanceA);

double NumberOfZones = 1;
for (int i = 2; i < openings.Count; i++)
{
if (NumberOfZones > 1) { ZoneLength = length; }
else { ZoneLength = sortedList.First().distanceA - sortedList.First().widthA; };
if (NumberOfZones > 1) { ZoneLength = length - sortedList.Last().distanceA; }
else { ZoneLength = 0; }
if (NumberOfZones > 2) { ZoneLength = openings.distanceA - sortedList[i - 1].distanceA; }
else { ZoneLength = 0; }
}

I managed to get the syntax working in isolation, but somehow i cant get my main code to umplement it. Thanks, Matthew

Tuesday, January 22, 2019 7:55 PM
• Hi matty1248,

For your question, I try to test the code you provided. But it is not completed, I could not reproduce.

What is the error message of the bold in your code? If it is possible, could you provide the code?

Best Regards,

Wendy

MSDN Community Support
Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

Wednesday, January 30, 2019 2:08 AM
• Hi Wendy,

thanks for your response. The code in that file is quite extensive and that file got corrupted somehow with me playing around with it too much. I've tried to reduce the problem down a little with the following code:

int O1 = 100;
int O2 = 50;
int O3 = 000;
int O4 = 150;

SortedDictionary<int, string> openings = new SortedDictionary<int, string>();

int NumberOfZones = 1;
foreach (KeyValuePair<int, string> p in openings)
{
if (p.Key > 0)
{ NumberOfZones += 1; }
for (int i = 1; i < openings.Count; i++)
{
int x = openings[i] - openings[i - 1];
}
}

With the last statement, in bold, i'm trying to subtract the previous key from the current for each iteration (except the first) so that i can then print the value of the difference between current and previous.

Thanks again,

Matthew

Wednesday, January 30, 2019 6:27 PM
• Hi matty1248,

I am not sure what you want to do for x. Hence I just fix the code for your reference.

``` int O1 = 100;
int O2 = 50;
int O3 = 000;
int O4 = 150;

SortedDictionary<string, int> openings = new SortedDictionary<string, int>();

int NumberOfZones = 1;

List<string> key = new List<string>();
foreach (var item in openings)
{
}
foreach (KeyValuePair<string, int> p in openings)
{
if (p.Value > 0)
{ NumberOfZones += 1; }

for (int i = 1; i <= key.Count; i++)
{
int x = openings[key[i]] - openings[key[i - 1]];
}
}```

Best Regards,

Wendy

MSDN Community Support
Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

• Marked as answer by Thursday, January 31, 2019 10:02 PM
Thursday, January 31, 2019 10:01 AM
• Hi Wendy,

thanks a lot for that, i totally broke my application but, in the end i need to use it to plot lines to a canvas. This works great though and once i've got my app working again, probably on the weekend, I think I can format this to suit. Thanks again,

Matthew

Thursday, January 31, 2019 10:05 PM