1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251
|
/**
Array.c
Global array helper functions.
@author Zapper, Sven2
*/
// Concatenates two arrays and returns a new array.
global func Concatenate(array first, array second)
{
var len_first = GetLength(first);
var result = CreateArray(len_first+GetLength(second));
result[:len_first] = first;
result[len_first:] = second;
return result;
}
// Returns a new array that contains the values of the first array minus the values of the second array.
global func Subtract(array subject, array subtract)
{
var diff = [];
for (var obj in subject)
{
var removed = false;
for (var rem_obj in subtract)
{
if (rem_obj == obj)
{
removed = true;
break;
}
}
if(!removed)
diff[GetLength(diff)] = obj;
}
return diff;
}
// Removes nil values from an array, returns the amount of values removed.
global func RemoveHoles(array leerdammer)
{
var move = 0;
var len = GetLength(leerdammer);
for (var i = 0; i < len; ++i)
{
if(leerdammer[i] == nil)
{
++move;
continue;
}
leerdammer[i - move] = leerdammer[i];
}
SetLength(leerdammer, len - move);
// assert IsGouda(leerdammer)
return move;
}
// Removes duplicate entries - returns the number of entries removed.
global func RemoveDuplicates(array arr)
{
var working = [];
var cnt = 0;
var len = GetLength(arr);
for (var i = 0; i < len; ++i)
{
if (IsValueInArray(working, arr[i]))
{
++cnt;
continue;
}
working[GetLength(working)] = arr[i];
}
SetLength(arr, GetLength(working));
for (var i = GetLength(working); --i >= 0;)
arr[i] = working[i];
return cnt;
}
// Tests whether a value is in an array.
global func IsValueInArray(array arr, /*any*/ value)
{
return GetIndexOf(arr, value) != -1;
}
// Removes a value from an array.
global func RemoveArrayValue(array arr, /*any*/ value, bool unstable)
{
var i = GetIndexOf(arr, value);
if (i == -1)
return false;
if (unstable == true)
return RemoveArrayIndexUnstable(arr, i);
return RemoveArrayIndex(arr, i);
}
// Randomly shuffles an array.
global func ShuffleArray(array arr)
{
var len = GetLength(arr);
var working = arr[:];
while (--len >= 0)
{
var i = Random(len + 1);
arr[len] = working[i];
working[i] = working[len];
}
return;
}
// Takes array of format [[x1,y1], [x2,y2], ...] and returns array [[x1,x2,...],[y1,y2,...]]
global func TransposeArray(array v)
{
var result = [], i = 0;
for (var vc in v)
{
var j = 0;
for (var c in vc)
{
if (!result[j])
result[j] = CreateArray(GetLength(v));
result[j][i] = c;
++j;
}
++i;
}
return result;
}
// Deletes an index from an array, does not change the order of items in the array.
global func RemoveArrayIndex(array arr, int index, bool unstable)
{
if (unstable == true)
return RemoveArrayIndexUnstable(arr, index);
// move all elements right of index to the left
arr[index:] = arr[index+1:];
return true;
}
// Deletes an array item - might change the order of elements, but is faster.
global func RemoveArrayIndexUnstable(array arr, int index)
{
arr[index] = arr[-1];
SetLength(arr, GetLength(arr) - 1);
return true;
}
// Inserts an element at the end of an array.
global func PushBack(array arr, /*any*/ value)
{
arr[GetLength(arr)] = value;
return true;
}
// Inserts an element at the beginning of an array.
global func PushFront(array arr, /*any*/ value)
{
// Move elements one to the right.
arr[1:] = arr;
arr[0] = value;
return true;
}
// Removes the last element from an array and returns it.
global func PopBack(array arr)
{
if (GetLength(arr) == 0)
return nil;
var o = arr[-1];
arr[:] = arr[:-1];
return o;
}
// Removes the first element from an array and returns it.
global func PopFront(array arr)
{
if (GetLength(arr) == 0)
return nil;
var o = arr[0];
arr[:] = arr[1:];
return o;
}
// Returns a random element from an array.
global func RandomElement(array arr)
{
return arr[Random(GetLength(arr))];
}
// Move array of indexes before given element. Called from editor on item move.
global func MoveArrayItems(array arr, array source_indices, int insert_before)
{
if (!arr) return false;
var len = GetLength(arr), off = 0, val;
// make sure source indices are sorted
if (len > 1)
{
source_indices = source_indices[:];
SortArray(source_indices);
}
for (var idx in source_indices)
{
if (idx < 0) idx += (1-(idx+1)/len)*len; // resolve negative indices
if (idx >= len) continue;
if (idx < insert_before)
{
// Move element forward
idx += off; --off; // Adjust for other elements already moved
val = arr[idx];
while (++idx < insert_before) arr[idx-1] = arr[idx];
arr[insert_before - 1] = val;
}
else
{
// Move element backward
val = arr[idx];
while (idx-- >= insert_before) arr[idx+1] = arr[idx];
arr[insert_before] = val;
++insert_before;
}
}
return true;
}
// Deletes multiple indexes from an array, does not change the order of items in the array.
global func RemoveArrayIndices(array arr, array indices)
{
indices = indices[:];
SortArray(indices, true);
for (var idx in indices)
if (idx < GetLength(arr))
RemoveArrayIndex(arr, idx);
return true;
}
// Performs a left fold.
//
// Examples:
// - Reduce([1, 2, 3, 4], Min) == 1
// - func Add(int a, int b) { return a + b; }
// Reduce([1, 2, 3, 4], Add, 100) == 110
global func Reduce(array arr, func fn, initial)
{
var i = 0;
var result = initial ?? arr[i++];
while (i < GetLength(arr))
result = Call(fn, result, arr[i++]);
return result;
}
|