1 module esstool.csvbuilder; 2 3 public class CSVBuilder 4 { 5 public string[][string] table; 6 private string[] keys; 7 8 this() 9 { 10 } 11 12 public void add(string key, string value) 13 { 14 import esstool.arrayutil : len; 15 16 orCreate(key); 17 this.addAt(key, value, len(this.table[key])); 18 } 19 20 public void addAt(string key, string value, int index) 21 { 22 import esstool.arrayutil : expandAndInsert; 23 24 orCreate(key); 25 this.table[key] = expandAndInsert(this.table[key], value, index, ""); 26 } 27 28 public void build(string file) 29 { 30 import std.file : write; 31 import esstool : StringBuilder; 32 33 StringBuilder builder = new StringBuilder(); 34 35 auto keys = this.keys; 36 foreach (string key; keys) 37 { 38 builder.append(key).append(","); 39 } 40 41 builder.removeLast().appendNewLine(); 42 43 for (int i = 0; i < this.tableLength(); i++) 44 { 45 foreach (string key; keys) 46 { 47 string[] arr = this.table[key]; 48 if (arr.length > i) 49 { 50 string value = arr[i]; 51 builder.append(value); 52 } 53 54 builder.append(","); 55 } 56 57 builder.removeLast().appendNewLine(); 58 } 59 60 write(file, builder.asString()); 61 } 62 63 public int tableLength() 64 { 65 import esstool.arrayutil : len; 66 67 int max = 0; 68 foreach (string key; this.keys) 69 { 70 int size = len(this.table[key]); 71 if (size > max) 72 { 73 max = size; 74 } 75 } 76 77 return max; 78 } 79 80 private void orCreate(string key) 81 { 82 import esstool.arrayutil : contains; 83 84 if (contains(this.keys, key)) 85 { 86 return; 87 } 88 89 this.keys ~= key; 90 this.table[key] = new string[0]; 91 92 } 93 }