0

I have a csv file that has 30 rows and 5 columns. I have this read into my application using stream reader, then put into an array, sorted, now being written out to the file. I have 5 columns that show "Score" followed with dashes beneath. My problem is I need to output my array in 5 columns after its sorted. I have a for loop that iterates through the length of the array. I really need it to iterate 30 lines and 5 columns, but I'm not sure how to do that. I apologize, but I am new to C# and features such as linq. Here is a short version of my output and the for loop. Let me know if further clarification is needed.

int n;

  fileOut.WriteLine();
  fileOut.WriteLine("Score    Score    Score    Score    Score");
  fileOut.WriteLine("-----    -----    -----    -----    -----");
  for (n = 1; n <= numOfScores; n++)
  fileOut.WriteLine("{0,4:f}", scoreArray[n]);
  fileOut.WriteLine();

I know there has to be an easy way to do this, just not sure.

The current output looks like:

Score    Score    Score    Score    Score
-----    -----    -----    -----    -----
97.05
96.52
93.16
92.44
91.05
90.66
90.59
//etc, etc, through entire array, only one line when it needs to be in each column.

Thanks, Joe

3 Answers 3

1

To do this properly, I first need to deal with your data. You have a sorted array of scores. You want this to output to columns, where the data fills down before filling across, via an output stream (the Console) that is strongly-biased towards writing across before it writes down.

This means in order to avoid back-tracking in the output stream (slow and tricky), we'll want to massage the data in memory before writing it to the console:

double[] scores = ...; //sorted data in here

// now some constants
const int cols = 5;
const int colWidth = 5;
const int colSpace = 4;
const string Header = "Score";

//figure out how many rows we need
int remainder = scores.Length % cols;
int rows = scores.Length / cols + (remainder > 0?1:0);

//organize the data into a 2d structure that matches the output
// I chose an array of arrays rather than 2d array so I can pass individual
//   arrays to format function later on.
var data = new string[rows][];
int i = 0; //score index
for (int c = 0;c < cols;c++)
{
    for (int r = 0;r < rows && i < scores.Length; r++)
    {
        //make sure nested array exists and is pre-populated with empty strings (string.Format() will choke later if we leave these as nulls)
        data[r] = data[r] ?? Enumerable.Repeat("", cols).ToArray();

        //skip this cell if it's at the bottom row of a later column in an unbalanced array
        if (remainder > 0 && r == rows - 1 && c >= remainder) continue;

        data[r][c] = scores[i].ToString();
        i++;
    }
}

//write the header
var format = string.Join("", Enumerable.Repeat("{0,-" + (colWidth + colSpace) + "}", cols));
Console.WriteLine(format, Header);
Console.WriteLine(format, new string('-', colWidth));

//write the data
format = string.Join("", Enumerable.Range(0,cols).Select(i => string.Format("{{{0},-{1}}}{2}", i, colWidth, new string(' ',colSpace))).ToArray());
for (int i = 0; i < rows; i++)
    Console.WriteLine(format, data[i]);

Running the code with this sample data:

double[] scores = { 97.05,96.52,93.16,92.44,91.05,90.66,90.59,19.1, 18.4, 16.8, 11.1, 13.8, 12.2, 7.9, 8.1, 11.0, 14.5, 16.6, 21.3, 16, 17.9};
scores = scores.OrderBy(s => s*-1).ToArray();

I get this result:

Score    Score    Score    Score    Score    
-----    -----    -----    -----    -----    
97.05    90.66    18.4     16       11.1     
96.52    90.59    17.9     14.5     11       
93.16    21.3     16.8     13.8     8.1      
92.44    19.1     16.6     12.2     7.9      
91.05                                                   

And the cool thing here is that this code will let you easily adjust the number of columns you want.

Sign up to request clarification or add additional context in comments.

1 Comment

That makes perfect sense on the ordering. Thank you!
0

It's a little weird that your array index would start with 1. It should start with 0 (unless you're skipping something on the first index?).

This is probably what you're looking for. Make sure that your index is not out of bounds (that your array is divisible by 5).

  fileOut.WriteLine();
  fileOut.WriteLine("Score    Score    Score    Score    Score");
  fileOut.WriteLine("-----    -----    -----    -----    -----");
  for (int n = 0; n < numOfScores; n+=5) // why do you need to declare n outside?
  {
            fileOut.WriteLine("{0,4:f} {1,4:f} {2,4:f} {3,4:f} {4,4:f}{5}", scoreArray[n],scoreArray[n+1],scoreArray[n+2],scoreArray[n+3],scoreArray[n+4],Environment.NewLine);
  }

9 Comments

I am skipping 0, and starting at one. It's hard to remember sometimes to start at 0, naturally, so I always null out position 0.
@Joe I would say that might not be a good practice if other people will see / use / edit your code as most programmers think it's intuitive that the index start from 0 :), but to each his own...does my answer work for what you want? Index issue aside.
This could lose some records at the end.
@Joe Yes. The fix is to sort it differently.
Yes and no. I fixed the array call, by changing scorArray[n] to [n + 1] since I am not using the 0 index. So everything prints out fine number wise.Its just not printing out the way I want. I have 5 columns of scores. Column one starts from 97.05 then going down vertically to 96.52 the 93.16 etc. This code is printing each number descending horizontally. Thats where I need a fix.
|
0

Instead of using Console.WriteLine, simply use Console.Write. Every time WriteLine is called, a new line character is printed following the input.

  fileOut.WriteLine();
  fileOut.WriteLine("Score    Score    Score    Score    Score");
  fileOut.WriteLine("-----    -----    -----    -----    -----");
  for (n = 1; n <= numOfScores; n++)
  fileOut.Write("{0,4:f}", scoreArray[n]);
  fileOut.WriteLine(); //do this so there is a new line after all the data

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.