theGreenCabbage
theGreenCabbage

Reputation: 4845

Unable to Reverse an Integer Array

I am currently creating a Legend component that maps text onto a gradient-looking legend that looks like this:

enter image description here

The central piece of code looks like the below (omitting the graphics declaration code snippets, as that's not the main piece):

        int numberOfItems = 10;
        int increment = (int) Math.Round((max - min), 0);
        int step = increment / numberOfItems;

Array that stores the step into an integer array the size of 10.

        int[] legend = new int[numberOfItems];
        for (int i = 0; i < legend.Length; i++) {
            legend[i] = step * i;
        }

String Reversal Code Snippet

        for (int i = (legend.Length - 1); i >= 0; i--) {
            g.DrawString(legend[i].ToString(), drawFontX, Brushes.White, ((newWidth / 2) - 5), (newHeight / 10) + (verticalDistance * i), stringFormatTimes);
        }

I have also tried:

        legend.Reverse();
        for (int i = 0; i < numberOfItems; i++) {
            g.DrawString(legend[i].ToString(), drawFontX, Brushes.White, ((newWidth / 2) - 5), (newHeight / 10) + (verticalDistance * i), stringFormatTimes);    
        }

As you can tell, I am trying to have the graph render the text from the largest value to the lowest, instead of what it is doing now, which is 0 - 1080.

My issue is, despite using both array reversal methods, I have been unable to reverse the legend array. I'm not quite sure what I am doing wrong.

Upvotes: 1

Views: 115

Answers (3)

Dan
Dan

Reputation: 9837

Try this:

legend = legend.Reverse().ToArray();

The problem is that the Reverse method you are using doesn't change the original object; it creates a new object with the items from the original in reverse order. But you weren't saving the result of the Reverse method. It was just being ignored. If you reassign the value of the legend variable to the result of the Reverse method, this should fix your problem.

Another option would be to use a List<int>:

List<int> legend = new List<int>(numberOfItems);
for (int i = 0; i < numberOfItems; i++) {
    legend.Add(step * i);
}

//...

legend.Reverse();

Here you would be calling the Reverse method on the List<T> class which does change the order of the calling list instead of returning a new instance.

Upvotes: 2

Dave Bish
Dave Bish

Reputation: 19646

You missed your assignment:

legend = legend.Reverse().ToArray();

Upvotes: 2

usr
usr

Reputation: 171178

legend.Reverse binds to Enumerable.Reverse which returns you a copy. This should teach you not to mutate state if you don't have to. Instead, create new data from old data.

var legendContents =
 Enumerable.Range(0, numberOfItems)
 .Select(i => step * i)
 .Reverse()
 .Select(i => new { Text = i.ToString(), Y = (newHeight / 10) + (verticalDistance * i) }
 .ToArray();

//at this point you can easily examine all draw operations in the debugger

var xPos = ((newWidth / 2) - 5);
foreach (var legendItem in legendContents)
 g.DrawString(legendItem.Text, drawFontX, Brushes.White, xPos, legendItem.Y, stringFormatTimes);    

Use a functional programming style. Much code saved, very readable now and easy to change.

Upvotes: 3

Related Questions