Skip to content

Instantly share code, notes, and snippets.

@Lanse505
Created December 27, 2021 20:09
Show Gist options
  • Save Lanse505/cb36be48bbb2580c931bee9297e49e9b to your computer and use it in GitHub Desktop.
Save Lanse505/cb36be48bbb2580c931bee9297e49e9b to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Assignment_2_Submission.programs.user.table{
public class TableWriter{
private List<object> Columns{ get; } // Column Content List
private List<object[]> Rows { get; set; } // Row Content List
// Constructor
public TableWriter(params string[] columns){
if (columns == null || columns.Length == 0){ // Checks whether the columns input is either null or empty
throw new ArgumentException("Input Arguments are either null or none provided!"); // Throws error if it is
}
Columns = new List<object>(columns); // Initializes the columns array with the input values
Rows = new List<object[]>(); // Initializes a default empty array of rows
}
// Adds the content rows to the table
public void AddRow(params object[] values){
// Input validation, throws if: The values param is null, The values param is empty, The values param doesn't match up with the columns size.
if (values == null || values.Length == 0 || values.Length != Columns.Count){
throw new ArgumentException("Input arguments are either: Null, Input values were 0, or the number of Input values didn't match the number of columns");
}
// If everything passes then add the values to the Rows list
Rows.Add(values);
}
// Gets a list of the greatest found sizes of entries in each column.
// Aka if row 4 has the longest string, it will get added to this list as the fourth entry.
private List<int> GetMaxStringLength(){
List<int> colSize = new List<int>();
// Cycles over each row and column and finds the longest possible entry for each column to determine the content width needed for the table.
for (int i = 0; i < Columns.Count; i++){
List<object> colRow = new List<object>();
int greatestLength = 0;
colRow.Add(Columns[i]);
colRow.AddRange(Rows.Select(t => t[i]));
for (int k = 0; k < colRow.Count; k++){
int length = colRow[k].ToString().Length;
if (length > greatestLength){
greatestLength = length;
}
}
colSize.Add(greatestLength);
}
// Returns the list of the widest value for each column
return colSize;
}
public override string ToString(){
StringBuilder tableString = new StringBuilder();
List<int> colSize = GetMaxStringLength();
// This handles and deals with formatting out rows and columns into something we can work with.
string rowFormat = Enumerable // Creates an Enumerable (Countable)
.Range(0, Columns.Count) // With a Range of 0-(Size of _columns)
.Select(size => " | {" + size + ",-" + colSize[size] + "}") // Loops through the range with the columns maximum length
.Aggregate((sum, nextValue) => sum + nextValue) + " |"; // Sums it all together
string columnHeaders = string.Format(rowFormat, Columns.ToArray()); // Creates the formatted Header string
List<string> values = Rows.Select(row => string.Format(rowFormat, row)).ToList(); // formats out rows and outputs them as a joint list of strings.
// Grabs the longest row length.
int maxRowSize = Math.Max(0, Rows.Any() ? Rows.Max(row => string.Format(rowFormat, row).Length) : 0);
// Finalizes the final table divider line size.
int maxColSize = Math.Max(maxRowSize, columnHeaders.Length);
string divLine = string.Join("", Enumerable.Repeat("-", Math.Max(maxColSize - 1, 0)));
string divider = $" {divLine} ";
// Time to build this Lego Table!
tableString.AppendLine(divider); // Adds the top divider line
tableString.AppendLine(columnHeaders); // adds the column header line
// Loops through all of our finalized row strings
foreach (var row in values){
tableString.AppendLine(divider); // Adds a divider line
tableString.AppendLine(row); // Adds the content row string
}
tableString.AppendLine(divider); // adds an ending divider line
return tableString.ToString();
}
// Prints the finalized table!
public void Print(){
Console.WriteLine(ToString());
}
public bool HasEntriesToPrint()
{
return Rows.Count > 0 && Columns.Count > 0;
}
public int GetCurrentIndex()
{
return Rows.Count - 1;
}
public int GetNextIndex()
{
return Rows.Count;
}
public void RemoveUser(int index)
{
Rows.RemoveAt(index);
var copy = new List<object[]>();
foreach (var row in Rows.AsEnumerable())
{
row[0] = copy.Count;
copy.Add(row);
}
Rows.Clear();
Rows = copy;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment