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/aa 6 ************************************************************************************************/ 7 module uim.core.containers.aa; 8 9 @safe: 10 import uim.core; 11 12 enum SORTED = true; 13 14 /// get keys of an associative array 15 @safe K[] getKeys(K, V)(V[K] aa, bool sorted = false) { 16 K[] results; 17 foreach(k, v; aa) results ~= k; 18 if (sorted) return results.sort.array; 19 return results; 20 } 21 unittest { 22 // Examples by value 23 assert([1:4, 2:5, 3:6].getKeys(SORTED) == [1, 2, 3]); 24 assert([1:"4", 2:"5", 3:"6"].getKeys(SORTED) == [1, 2, 3]); 25 assert(["1":4, "2":5, "3":6].getKeys(SORTED) == ["1", "2", "3"]); 26 assert(["1":"4", "2":"5", "3":"6"].getKeys(SORTED) == ["1", "2", "3"]); 27 28 // Examples by reference 29 class Test {} 30 auto a = new Test; 31 auto b = new Test; 32 auto c = new Test; 33 assert([1:a, 2:b, 3:c].getKeys(SORTED) == [1, 2, 3]); 34 } 35 36 /// get values of an associative array - currently not working für objects 37 @safe V[] getValues(K, V)(V[K] aa, bool sorted = false) { 38 V[] results; 39 foreach(k, v; aa) results ~= v; 40 if (sorted) return results.sort.array; 41 return results; 42 } 43 unittest { 44 assert([1:4, 2:5, 3:6].getValues(SORTED) == [4, 5, 6]); 45 assert([1:"4", 2:"5", 3:"6"].getValues(SORTED) == ["4", "5", "6"]); 46 assert(["1":4, "2":5, "3":6].getValues(SORTED) == [4, 5, 6]); 47 assert(["1":"4", "2":"5", "3":"6"].getValues(SORTED) == ["4", "5", "6"]); 48 } 49 50 // Add Items from array 51 @safe T[S] add(T, S)(T[S] baseItems, T[S] addItems) { 52 T[S] results = baseItems.dup; 53 foreach(k, v; addItems) results[k] = v; 54 return results; 55 } 56 unittest { 57 assert([1:"b", 2:"d"].add([3:"f"]) == [1:"b", 2:"d", 3:"f"]); 58 assert(["a":"b", "c":"d"].add(["e":"f"]) == ["a":"b", "c":"d", "e":"f"]); 59 assert(["a":"b", "c":"d"].add(["e":"f"]).add(["g":"h"]) == ["a":"b", "c":"d", "e":"f", "g":"h"]); 60 } 61 62 /// remove subItems from baseItems if key and value of item are equal 63 @safe T[S] sub(T, S)(T[S] baseItems, T[S] subItems) { 64 T[S] results = baseItems.dup; 65 foreach(k, v; subItems) 66 if ((k in results) && (results[k] == v)) results.remove(k); 67 return results; 68 } 69 unittest { 70 assert([1:"4", 2:"5", 3:"6"].sub([1:"5", 2:"5", 3:"6"]) == [1:"4"]); 71 } 72 73 /// remove subItems from baseItems if key exists 74 @safe T[S] subKeys(T, S)(T[S] baseItems, S[] subItems...) { 75 return subKeys(baseItems, subItems); 76 } 77 unittest { 78 assert([1:"4", 2:"5", 3:"6"].subKeys(2, 3) == [1:"4"]); 79 } 80 81 /// remove subItems from baseItems if key exists 82 @safe T[S] subKeys(T, S)(T[S] baseItems, S[] subItems) { 83 T[S] results = baseItems.dup; 84 foreach(key; subItems) results.remove(key); 85 return results; 86 } 87 unittest { 88 assert([1:"4", 2:"5", 3:"6"].subKeys([2, 3]) == [1:"4"]); 89 } 90 91 /// remove subItems from baseItems if key exists 92 @safe T[S] subKeys(T, S)(T[S] baseItems, T[S] subItems) { 93 T[S] results = baseItems.dup; 94 foreach(k, v; subItems) results.remove(k); 95 return results; 96 } 97 unittest { 98 assert([1:"4", 2:"5", 3:"6"].subKeys([2:"x", 3:"y"]) == [1:"4"]); 99 } 100 101 /// remove subItems from baseItems if value exists 102 @safe T[S] subValues(T, S)(T[S] baseItems, T[S] subItems) { 103 T[S] results = baseItems.dup; 104 foreach(k, v; subItems) { 105 foreach(kk, vv; baseItems) if (v == vv) results.remove(kk); 106 } 107 return results; 108 } 109 unittest { 110 assert([1:"4", 2:"5", 3:"6"].subValues([2:"5", 3:"6"]) == [1:"4"]); 111 assert([7:"4", 8:"5", 9:"6"].subValues([2:"5", 3:"6"]) == [7:"4"]); 112 assert([7:"4", 8:"5", 9:"6"].subValues([2:"2", 3:"2"]) != [7:"4"]); 113 114 assert([1:4, 2:5, 3:6].subValues([2:5, 3:6]) == [1:4]); 115 assert([7:4, 8:5, 9:6].subValues([2:5, 3:6]) == [7:4]); 116 assert([7:4, 8:5, 9:6].subValues([2:2, 3:2]) != [7:4]); 117 } 118 119 @safe pure size_t[T] indexAA(T)(T[] values, size_t startPos = 0) { 120 size_t[T] results; 121 foreach(i, value; values) results[value] = i + startPos; 122 return results; 123 } 124 unittest { 125 assert(["a", "b", "c"].indexAA == ["a":0UL, "b":1UL, "c":2UL]); 126 assert(["a", "b", "c"].indexAA(1) == ["a":1UL, "b":2UL, "c":3UL]); 127 } 128 129 @safe pure size_t[T] indexAAReverse(T)(T[] values, size_t startPos = 0) { 130 size_t[T] results; 131 foreach(i, value; values) results[i + startPos] = value; 132 return results; 133 } 134 unittest { 135 // 136 } 137 138 @safe bool hasKey(T, S)(T[S] base, S key) { return (key in base) ? true : false; } 139 @safe bool hasKeys(T, S)(T[S] base, S[] keys...) { return base.hasKeys(keys); } 140 @safe bool hasKeys(T, S)(T[S] base, S[] keys) { bool result; foreach(key; keys) if (key !in base) return false; return true; } 141 unittest { 142 assert(["a":"b", "c":"d"].hasKey("a")); 143 assert(["a":"b", "c":"d"].hasKeys("a")); 144 assert(["a":"b", "c":"d"].hasKeys("a", "c")); 145 assert(["a":"b", "c":"d"].hasKeys(["a"])); 146 assert(["a":"b", "c":"d"].hasKeys(["a", "c"])); 147 } 148 149 @safe bool hasValue(T, S)(T[S] base, S value...) { foreach(v; base.getValues) if (v == value) return true; return false; } 150 @safe bool hasValues(T, S)(T[S] base, S[] values...) { return base.hasValues(values); } 151 @safe bool hasValues(T, S)(T[S] base, S[] values) { foreach(value; values) if (!base.hasValue(value)) return false; return true; } 152 unittest { 153 assert(["a":"b", "c":"d"].hasValue("b")); 154 assert(["a":"b", "c":"d"].hasValues("b")); 155 assert(["a":"b", "c":"d"].hasValues("b", "d")); 156 assert(["a":"b", "c":"d"].hasValues(["b"])); 157 assert(["a":"b", "c":"d"].hasValues(["b", "d"])); 158 } 159 160 @safe pure string toJSONString(T)(T[string] values, bool sorted = false) { 161 string[] result; 162 163 foreach(k; values.getKeys(sorted)) result ~= `"%s":%s`.format(k, values[k]); 164 165 return "{"~result.join(",")~"}"; 166 } 167 unittest { 168 assert(["a":1, "b":2].toJSONString(SORTED) == `{"a":1,"b":2}`); 169 } 170 171 @safe pure string toHTML(T)(T[string] values, bool sorted = false) { 172 string[] results; 173 foreach(k; values.getKeys(sorted)) { 174 results ~= `%s="%s"`.format(k, values[k]); 175 } 176 return results.join(" "); 177 } 178 unittest { 179 assert(["a":1, "b":2].toHTML(SORTED) == `a="1" b="2"`); 180 } 181 182 @safe pure string toSqlUpdate(T)(T[string] values, bool sorted = false) { 183 string[] results; 184 foreach(k; values.getKeys(sorted)) results ~= `%s=%s`.format(k, values[k]); 185 return results.join(","); 186 } 187 unittest { 188 assert(["a":1, "b":2].toSqlUpdate(SORTED) == `a=1,b=2`); 189 }