CsvWriter.cs
1 using Logging; 2 3 namespace TranscriptAnalysis 4 { 5 public class CsvWriter 6 { 7 private readonly ILog log; 8 9 public CsvWriter(ILog log) 10 { 11 this.log = log; 12 } 13 14 public ICsv CreateNew() 15 { 16 return new Csv(); 17 } 18 19 public void Write(ICsv csv, string filename) 20 { 21 var c = (Csv)csv; 22 23 using var file = File.OpenWrite(filename); 24 using var writer = new StreamWriter(file); 25 c.CreateLines(writer.WriteLine); 26 27 log.Log($"CSV written to: '{filename}'"); 28 } 29 } 30 31 public interface ICsv 32 { 33 ICsvColumn GetColumn(string title, float defaultValue); 34 ICsvColumn GetColumn(string title, string defaultValue); 35 void AddRow(params CsvCell[] cells); 36 } 37 38 public class Csv : ICsv 39 { 40 private readonly string Sep = ","; 41 private readonly List<CsvColumn> columns = new List<CsvColumn>(); 42 private readonly List<CsvRow> rows = new List<CsvRow>(); 43 44 public ICsvColumn GetColumn(string title, float defaultValue) 45 { 46 return GetColumn(title, defaultValue.ToString()); 47 } 48 49 public ICsvColumn GetColumn(string title, string defaultValue) 50 { 51 var column = columns.SingleOrDefault(c => c.Title == title); 52 if (column == null) 53 { 54 column = new CsvColumn(title, defaultValue); 55 columns.Add(column); 56 } 57 return column; 58 } 59 60 public void AddRow(params CsvCell[] cells) 61 { 62 rows.Add(new CsvRow(cells)); 63 } 64 65 public void CreateLines(Action<string> onLine) 66 { 67 CreateHeaderLine(onLine); 68 foreach (var row in rows) 69 { 70 CreateRowLine(row, onLine); 71 } 72 } 73 74 private void CreateHeaderLine(Action<string> onLine) 75 { 76 onLine(string.Join(Sep, columns.Select(c => c.Title).ToArray())); 77 } 78 79 private void CreateRowLine(CsvRow row, Action<string> onLine) 80 { 81 onLine(string.Join(Sep, columns.Select(c => GetRowCellValue(row, c)).ToArray())); 82 } 83 84 private string GetRowCellValue(CsvRow row, CsvColumn column) 85 { 86 var cell = row.Cells.SingleOrDefault(c => c.Column == column); 87 if (cell == null) return column.DefaultValue; 88 return cell.Value; 89 } 90 } 91 92 public class CsvCell 93 { 94 public CsvCell(ICsvColumn column, float value) 95 : this(column, value.ToString()) 96 { 97 } 98 99 public CsvCell(ICsvColumn column, string value) 100 { 101 Column = column; 102 Value = value; 103 } 104 105 public ICsvColumn Column { get; } 106 public string Value { get; } 107 } 108 109 public interface ICsvColumn 110 { 111 string Title { get; } 112 string DefaultValue { get; } 113 } 114 115 public class CsvColumn : ICsvColumn 116 { 117 public CsvColumn(string title, string defaultValue) 118 { 119 Title = title; 120 DefaultValue = defaultValue; 121 } 122 123 public string Title { get; } 124 public string DefaultValue { get; } 125 } 126 127 public class CsvRow 128 { 129 public CsvRow(CsvCell[] cells) 130 { 131 Cells = cells; 132 } 133 134 public CsvCell[] Cells { get; } 135 } 136 }