1 module dlq; 2 3 unittest 4 { 5 import std.stdio; 6 import std..string; 7 8 assert(["a", "b", "c"].first!(s => s == "b") == "b"); 9 assert(["a","a","b","b"].distinct == ["a", "b"]); 10 } 11 import std.exception; 12 13 /// Returns the first element in an array that meets the conditionition 14 T first(alias condition = x => true, T)(T[] source) 15 { 16 enforce(source.length > 0, "Array length cannot be 0"); 17 foreach (k; source) 18 { 19 if (condition(k)) 20 return k; 21 } 22 return null; 23 } 24 25 /// Returns the first element in an array that meets the conditionition 26 T firstOrDefault(alias condition = x => true, T)(T[] source) 27 { 28 enforce(source.length > 0, "Array length cannot be 0"); 29 foreach (k; source) 30 { 31 if (condition(k)) 32 return k; 33 } 34 return null; 35 } 36 37 /// Returns the last element in an array that meets the condition 38 T last(alias condition = x => true, T)(T[] source) 39 { 40 for (int i = source.length; i >= 0; i--) 41 { 42 T v = source[i]; 43 if (condition(v)) 44 return v; 45 } 46 } 47 48 /// Returns an array of elements that meet the condition 49 T[] where(alias condition = x => true, T)(T[] source) 50 { 51 T[] results; 52 foreach (k; source) 53 { 54 if (condition(k)) 55 results ~= k; 56 } 57 return results; 58 } 59 60 /// Checks if array contains one or more item that meets the condition 61 bool any(alias condition = x => true, T)(T[] source) 62 { 63 foreach (k; source) 64 { 65 if (condition(k)) 66 return true; 67 } 68 return false; 69 } 70 71 /// Counts how many items meet the conditions 72 int count(alias condition = x => true, T)(T[] source) 73 { 74 int i = 0; 75 foreach (k; source) 76 { 77 if (condition(k)) 78 i++; 79 } 80 return i; 81 } 82 83 /// Counts how many items meet the conditions 84 long longCount(alias condition = x => true, T)(T[] source) 85 { 86 long i = 0; 87 foreach (k; source) 88 { 89 if (condition(k)) 90 i++; 91 } 92 return i; 93 } 94 95 // HACK 96 // TODO 97 // Get rid of TResult and figure out the type from the delegate, 98 // probably use something like ReturnType!selector[] but it doesn't work 99 // 100 // Currently: 101 // ["a","b","c"].select!(x => x.toLower, string) 102 // 103 // Goal: 104 // ["a","b","c"].select!(x => x.toLower) 105 106 /// Selects specified members from objects 107 TResult[] select(alias selector, TResult, TSource)(TSource[] source) 108 { 109 TResult[] results; 110 foreach (k; source) 111 { 112 results ~= selector(k); 113 } 114 return results; 115 } 116 117 /// Returns an array of distinct items 118 T[] distinct(T)(T[] source) 119 { 120 T[] results; 121 foreach (k; source) 122 { 123 if (!(results.contains(k))) 124 results ~= k; 125 } 126 return results; 127 } 128 129 /// Check if an array contains an item 130 bool contains(T)(T[] source, T item) 131 { 132 return source.any!(i => i == item); 133 } 134 135 /// Returns the largest item in the array 136 T max(T)(T[] source) 137 { 138 T max; 139 foreach (k; source) 140 { 141 if (k > max) 142 max = k; 143 } 144 return max; 145 } 146 147 /// Returns the smallest item in the array 148 T min(T)(T[] source) 149 { 150 T min; 151 foreach (k; source) 152 { 153 if (k < min) 154 min = k; 155 } 156 return min; 157 } 158 159 /// Returns the average value of all items in the array 160 T average(T)(T[] source) 161 { 162 return source.sum / source.length; 163 } 164 165 /// Retuns the sum of all values in the array 166 T sum(T)(T[] source) 167 { 168 foreach (k; source) 169 { 170 sum ~= k; 171 } 172 return sum / source.length; 173 } 174 175 /// Sorts the elements of a sequence in ascending order according to a key 176 T[] orderBy(alias func, T)(T[] source) 177 { 178 import std.algorithm.sorting; 179 180 alias compare = (x, y) => func(x) > func(y); 181 return source.sort!(compare).release; 182 } 183 184 /// Sorts the elements of a sequence in descending order according to a key 185 T[] orderByDescending(alias func = a => a, T)(T[] source) 186 { 187 import std.algorithm.sorting; 188 189 alias compare = (x, y) => func(x) < func(y); 190 return source.sort!(compare).release; 191 }