Added support for sorting associative arrays by keys or values (from Mr.Stalin)

This commit is contained in:
NovaRain
2019-01-07 15:13:22 +08:00
parent 5611931063
commit 4f48926105
3 changed files with 69 additions and 19 deletions
+1
View File
@@ -169,6 +169,7 @@ Example:
- if used on list, "key" must be numeric and within valid index range (0..size-1)
- if used on map, key can be of any type
- to "unset" a value from map, just set it to zero (0)
- NOTE: to add a value of 0 for the key, use the float value (0.0)
- this works exactly like statement:
arrayID[key] := value;
+8 -4
View File
@@ -114,14 +114,18 @@
#define array_exists(array) (len_array(array) != -1)
// remove all elements from array
#define clear_array(array) resize_array(array, 0)
// sort array in ascending order
// sort array or map by key in ascending order
#define sort_array(array) resize_array(array, -2)
// sort array in descending order
// sort array or map by key in descending order
#define sort_array_reverse(array) resize_array(array, -3)
// reverse elements in list
// reverse elements in list/map
#define reverse_array(array) resize_array(array, -4)
// randomly shuffle elements in list
// randomly shuffle elements in list/map
#define shuffle_array(array) resize_array(array, -5)
// sort map in ascending order by value
#define sort_map_value(array) resize_array(array, -6)
// sort map in descending order by value
#define sort_map_value_desc(array) resize_array(array, -7)
// remove element from map or just replace value with 0 for list
#define unset_array(array, item) set_array(array, item, 0)
// same as "key_pressed" but checks VK codes instead of DX codes
+60 -15
View File
@@ -498,6 +498,60 @@ int _stdcall LenArray(DWORD id) {
else return arrays[id].size();
}
template <class T>
static void ListSort(std::vector<T> &arr, int type) {
switch (type) {
case ARRAY_ACTION_SORT: // sort ascending
std::sort(arr.begin(), arr.end());
break;
case ARRAY_ACTION_RSORT: // sort descending
std::sort(arr.rbegin(), arr.rend());
break;
case ARRAY_ACTION_REVERSE: // reverse elements
std::reverse(arr.rbegin(), arr.rend());
break;
case ARRAY_ACTION_SHUFFLE: // shuffle elements
std::random_shuffle(arr.rbegin(), arr.rend());
break;
}
}
static void MapSort(sArrayVar& arr, int type) {
std::vector<std::pair<sArrayElement, sArrayElement>> map;
bool sortByValue = false;
if (type < ARRAY_ACTION_SHUFFLE) {
type += 4;
sortByValue = true;
}
sArrayElement key, val;
for (size_t i = 0; i < arr.val.size(); ++i) {
if (sortByValue) {
val = arr.val[i++]; // map key > value
key = arr.val[i]; // map value > key
} else {
key = arr.val[i]; // key
val = arr.val[++i]; // value
}
map.push_back(std::make_pair(key, val));
}
ListSort(map, type);
arr.val.clear();
arr.keyHash.clear();
for (size_t i = 0; i < map.size(); ++i) {
size_t el = arr.val.size();
if (sortByValue) {
arr.val.push_back(map[i].second); // map value > key
arr.val.push_back(map[i].first); // map key > value
} else {
arr.val.push_back(map[i].first);
arr.val.push_back(map[i].second);
}
arr.keyHash[arr.val[el]] = el;
}
}
void _stdcall ResizeArray(DWORD id, int newlen) {
if (newlen == -1 || arrays.find(id) == arrays.end() || arrays[id].size() == newlen) return;
sArrayVar &arr = arrays[id];
@@ -514,7 +568,11 @@ void _stdcall ResizeArray(DWORD id, int newlen) {
arr.clearRange(actualLen);
arr.val.resize(actualLen);
} else if (newlen < 0) {
DebugPrintf("\nOPCODE ERROR: resize_array() - array sorting error.");
if (newlen < (ARRAY_ACTION_SHUFFLE - 2)) {
DebugPrintf("\nOPCODE ERROR: resize_array() - array sorting error.");
return;
}
MapSort(arr, newlen);
}
return;
}
@@ -529,20 +587,7 @@ void _stdcall ResizeArray(DWORD id, int newlen) {
DebugPrintf("\nOPCODE ERROR: resize_array() - array sorting error.");
return;
}
switch (newlen) {
case ARRAY_ACTION_SORT: // sort ascending
std::sort(arr.val.begin(), arr.val.end());
break;
case ARRAY_ACTION_RSORT: // sort descending
std::sort(arr.val.rbegin(), arr.val.rend());
break;
case ARRAY_ACTION_REVERSE: // reverse elements
std::reverse(arr.val.rbegin(), arr.val.rend());
break;
case ARRAY_ACTION_SHUFFLE: // shuffle elements
std::random_shuffle(arr.val.rbegin(), arr.val.rend());
break;
}
ListSort(arr.val, newlen);
}
}