1 /*********************************************************************************************** 2 * Copyright: © 2017-2021 UI Manufaktur UG 3 * License: Subject to the terms of the MIT license, as written in the included LICENSE.txt file. 4 * Authors: UI Manufaktur Team 5 * Documentation [DE]: https://ui-manufaktur.com/docu/uim-core/containers/arry 6 ************************************************************************************************/ 7 module uim.core.containers.array_; 8 9 @safe: 10 import uim.core; 11 12 /// Counts appearance of equal items 13 auto countsEquals(T)(in T[] baseArray...) { 14 return countsEquals(baseArray, null); 15 } 16 unittest { 17 assert(countsEquals(1) == [1:1uL]); 18 assert(countsEquals(1, 1) == [1:2uL]); 19 assert(countsEquals(1, 2) == [1:1U, 2:1UL]); 20 } 21 22 /// Counts the occourence of values in an array 23 auto countsEquals(T)(in T[] baseArray, in T[] validValues = null) { 24 size_t[T] results; 25 auto checkValues = (validValues ? baseArray.filters(validValues) : baseArray); 26 foreach(v; checkValues) { 27 if (v in results) results[v]++; 28 else results[v] = 1; 29 } 30 return results; 31 } 32 unittest { 33 assert(countsEquals([1]) == [1:1uL]); 34 assert(countsEquals([1, 1]) == [1:2uL]); 35 assert(countsEquals([1, 2]) == [1:1uL, 2:1uL]); 36 assert(countsEquals([1, 2], [1]) == [1:1uL]); 37 } 38 39 auto firstPosition(T)(in T[] baseArray, in T value) { 40 foreach(index, item; baseArray) if (item == value) return index; 41 return -1; 42 } 43 unittest { 44 } 45 46 /// Creates a associative array with all positions of a value in an array 47 auto positions(T)(in T[] baseArray...) { 48 size_t[][T] results = positions(baseArray, null); 49 return results; } 50 unittest { 51 assert(positions(1) == [1:[0UL]]); 52 assert(positions(1, 1) == [1:[0UL, 1UL]]); 53 assert(positions(1, 2) == [1:[0UL], 2:[1UL]]); 54 } 55 56 /// Creates a associative array with all positions of a value in an array 57 size_t[][T] positions(T)(in T[] baseArray, in T[] validValues = null) { 58 size_t[][T] results; 59 auto checkValues = (validValues ? baseArray.filters(validValues) : baseArray); 60 foreach(pos, v; checkValues) { 61 if (v in results) results[v] ~= pos; 62 else results[v] = [pos]; 63 } 64 return results; 65 } 66 unittest { 67 assert(positions([1]) == [1:[0UL]]); 68 assert(positions([1, 1]) == [1:[0UL, 1UL]]); 69 assert(positions([1, 2]) == [1:[0UL], 2:[1UL]]); 70 assert(positions([1, 2], [1]) == [1:[0UL]]); 71 } 72 73 /// adding items into array 74 @safe T[] add(T)(in T[] baseArray, in T[] newItems...) { 75 return add(baseArray, newItems); 76 } 77 unittest { 78 assert([1,2,3].add(4) == [1,2,3,4]); 79 assert([1,2,3].add(4,5) == [1,2,3,4,5]); 80 assert([1.0,2.0,3.0].add(4.0,5.0) == [1.0,2.0,3.0,4.0,5.0]); 81 assert(["1","2","3"].add("4","5") == ["1","2","3","4","5"]); 82 } 83 84 /// adding items into array 85 @safe T[] add(T)(in T[] baseArray, in T[] newItems) { 86 T[] results = baseArray.dup; 87 results ~= newItems; 88 return results; 89 } 90 unittest { 91 assert([1,2,3].add([4,5]) == [1,2,3,4,5]); 92 assert([1.0,2.0,3.0].add([4.0,5.0]) == [1.0,2.0,3.0,4.0,5.0]); 93 assert(["1","2","3"].add(["4","5"]) == ["1","2","3","4","5"]); 94 } 95 96 /// change positions 97 @safe void change(T)(ref T left, ref T right) { 98 T buffer = left; 99 left = right; 100 right = buffer; 101 } 102 /// Changing positions of elements in array 103 @safe T[] change(T)(T[] values, size_t firstPosition, size_t secondPosition) { 104 if ((firstPosition >= values.length) || (secondPosition >= values.length) || (firstPosition == secondPosition)) return values; 105 106 T[] results = values.dup; 107 T buffer = results[firstPosition]; 108 results[firstPosition] = results[secondPosition]; 109 results[secondPosition] = buffer; 110 return results; 111 } 112 unittest{ 113 assert(change([1, 2, 3, 4], 1, 2) == [1, 3, 2, 4]); 114 assert(change(["a", "b", "c", "d"], 3, 2) == ["a", "b", "d", "c"]); 115 assert(change(["a", "b", "c", "d"], 1, 1) == ["a", "b", "c", "d"]); 116 assert(change(["a", "b", "c", "d"], 1, 9) == ["a", "b", "c", "d"]); 117 } 118 119 // sub 120 @safe T[] sub(T)(T[] lhs, T rhs, bool multiple = false) { 121 auto result = lhs.dup; 122 if (multiple) { while(rhs.isIn(result)) result = result.sub(rhs); } 123 else foreach(i, value; result) { 124 if (value == rhs) { 125 result = result.remove(i); 126 break; 127 } 128 } 129 return result; 130 } 131 unittest { 132 assert([1, 2, 3].sub(2) == [1, 3]); 133 assert([1, 2, 3, 2].sub(2, true) == [1, 3]); 134 } 135 136 // sub(T)(T[] lhs, T[] rhs, bool multiple = false) 137 @safe T[] sub(T)(T[] lhs, T[] rhs, bool multiple = false) { 138 auto result = lhs.dup; 139 foreach(v; rhs) lhs = lhs.sub(v, multiple); 140 return lhs; 141 } 142 unittest { 143 assert([1, 2, 3].sub([2]) == [1, 3]); 144 assert([1, 2, 3, 2].sub([2], true) == [1, 3]); 145 assert([1, 2, 3, 2].sub([2, 3], true) == [1]); 146 assert([1, 2, 3, 2, 3].sub([2, 3], true) == [1]); 147 } 148 149 // filters(T)(T[] lhs, T[] rhs, bool multiple = false) 150 @safe T[] filters(T)(T[] baseArray, T[] filterValues...) { 151 return filters(baseArray, filterValues); 152 } 153 unittest { 154 assert([1, 2, 3].filters(2) == [2]); 155 assert([1, 2, 3].filters() == []); 156 assert([1, 2, 3].filters(1, 2) == [1, 2]); 157 } 158 159 @safe T[] filters(T)(T[] baseArray, T[] filterValues) { 160 T[] results; 161 foreach(v; baseArray) if (filterValues.has(v)) results ~= v; 162 return results; 163 } 164 unittest { 165 assert([1, 2, 3].filters([2]) == [2]); 166 assert([1, 2, 3].filters([]) == []); 167 } 168 169 @safe OUT[] castTo(OUT, IN)(IN[] values) { 170 OUT[] results; results.length = values.length; 171 foreach(i, value; value) result[i] = to!OUT(value); 172 return results; 173 } 174 175 unittest { 176 auto values = [1, 2, 3, 4]; 177 change(values[2], values[3]); 178 assert(values == [1, 2, 4, 3]); 179 180 assert([1,2,3,4].change(1, 3) == [1, 4, 3, 2]); 181 } 182 183 bool exist(T)(in T[] values, in T[] checkValues...) { 184 return has(values, checkValues); 185 } 186 bool has(T)(in T[] values, in T[] checkValues...) { 187 return has(values, checkValues); 188 } 189 unittest { 190 assert([1,2,3,4].has(1)); 191 assert(![1,2,3,4].has(5)); 192 assert([1,2,3,4].has(1, 2)); 193 assert(![1,2,3,4].has(5, 1)); 194 } 195 196 bool has(T)(in T[] values, in T[] checkValues) { 197 bool result = false; 198 foreach (cv; checkValues) { 199 result = false; 200 foreach (value; values) if (value == cv) result = true; 201 if (!result) return false; 202 } 203 return result; 204 } 205 unittest { 206 assert([1,2,3,4].has([1])); 207 assert(![1,2,3,4].has([5])); 208 assert([1,2,3,4].has([1, 2])); 209 assert(![1,2,3,4].has([5, 1])); 210 } 211 212 size_t index(T)(T[] values, T value) { 213 foreach (count, key; values) if (key == value) return count; 214 return -1; 215 } 216 unittest { 217 assert([1,2,3,4].index(1) == 0); 218 assert([1,2,3,4].index(0) == -1); 219 } 220 221 size_t[] indexes(T)(T[] values, T value) { 222 size_t[] results; 223 foreach (count, key; values) if (key == value) results ~= count; 224 return results; 225 } 226 unittest { 227 assert([1,2,3,4].indexes(1) == [0]); 228 assert([1,2,3,4].indexes(0) == null); 229 assert([1,2,3,4,1].indexes(1) == [0,4]); 230 } 231 232 size_t[][T] indexes(T)(T[] values, T[] keys) { 233 size_t[][T] results; 234 foreach (key; keys) results[key] = indexes(values, key); 235 return results; 236 } 237 unittest { 238 assert([1,2,3,4].indexes([1]) == [1:[0UL]]); 239 assert([1,2,3,4,1].indexes([1]) == [1:[0UL, 4UL]]); 240 }