@oscarpalmer/atoms 0.167.0 → 0.168.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/array/index.d.mts +1 -2
- package/dist/array/index.mjs +1 -2
- package/dist/array/sort.d.mts +29 -5
- package/dist/array/sort.mjs +27 -14
- package/dist/index.d.mts +116 -92
- package/dist/index.mjs +167 -154
- package/package.json +5 -1
- package/src/array/index.ts +0 -1
- package/src/array/sort.ts +100 -63
- package/src/index.ts +1 -0
package/dist/array/index.d.mts
CHANGED
|
@@ -15,11 +15,10 @@ import { ArrayPosition, endsWithArray, getArrayPosition, includesArray, indexOfA
|
|
|
15
15
|
import { push } from "./push.mjs";
|
|
16
16
|
import { select } from "./select.mjs";
|
|
17
17
|
import { drop, slice, take } from "./slice.mjs";
|
|
18
|
-
import { ArrayComparisonSorter, ArrayKeySorter, ArrayValueSorter, SORT_DIRECTION_ASCENDING, SORT_DIRECTION_DESCENDING, SortDirection, sort } from "./sort.mjs";
|
|
19
18
|
import { splice } from "./splice.mjs";
|
|
20
19
|
import { toSet } from "./to-set.mjs";
|
|
21
20
|
import { toggle } from "./toggle.mjs";
|
|
22
21
|
import { union } from "./union.mjs";
|
|
23
22
|
import { unique } from "./unique.mjs";
|
|
24
23
|
import { update } from "./update.mjs";
|
|
25
|
-
export {
|
|
24
|
+
export { ArrayPosition, chunk, compact, difference, drop, endsWithArray, exists, find, flatten, getArray, getArrayPosition, includesArray, indexOf, indexOfArray, insert, intersection, partition, push, range, select, shuffle, slice, splice, startsWithArray, take, times, toSet, toggle, union, unique, update };
|
package/dist/array/index.mjs
CHANGED
|
@@ -15,11 +15,10 @@ import { endsWithArray, getArrayPosition, includesArray, indexOfArray, startsWit
|
|
|
15
15
|
import { push } from "./push.mjs";
|
|
16
16
|
import { select } from "./select.mjs";
|
|
17
17
|
import { drop, slice, take } from "./slice.mjs";
|
|
18
|
-
import { SORT_DIRECTION_ASCENDING, SORT_DIRECTION_DESCENDING, sort } from "./sort.mjs";
|
|
19
18
|
import { splice } from "./splice.mjs";
|
|
20
19
|
import { toSet } from "./to-set.mjs";
|
|
21
20
|
import { toggle } from "./toggle.mjs";
|
|
22
21
|
import { union } from "./union.mjs";
|
|
23
22
|
import { unique } from "./unique.mjs";
|
|
24
23
|
import { update } from "./update.mjs";
|
|
25
|
-
export {
|
|
24
|
+
export { chunk, compact, difference, drop, endsWithArray, exists, find, flatten, getArray, getArrayPosition, includesArray, indexOf, indexOfArray, insert, intersection, partition, push, range, select, shuffle, slice, splice, startsWithArray, take, times, toSet, toggle, union, unique, update };
|
package/dist/array/sort.d.mts
CHANGED
|
@@ -35,6 +35,10 @@ type ArrayKeySorter<Item extends PlainObject, ItemKey extends keyof Item> = {
|
|
|
35
35
|
* Sorters based on keys in an object
|
|
36
36
|
*/
|
|
37
37
|
type ArrayKeySorters<Item extends PlainObject> = { [ItemKey in keyof Item]: ArrayKeySorter<Item, ItemKey> }[keyof Item];
|
|
38
|
+
/**
|
|
39
|
+
* Sorter to use for sorting
|
|
40
|
+
*/
|
|
41
|
+
type ArraySorter<Item> = Item extends PlainObject ? keyof Item | ArrayComparisonSorter<Item> | ArrayKeySorters<Item> | ArrayValueSorter<Item> | ComparisonSorter<Item> : ArrayComparisonSorter<Item> | ArrayValueSorter<Item> | ComparisonSorter<Item>;
|
|
38
42
|
/**
|
|
39
43
|
* Sorting information for arrays _(using a value callback and built-in comparison)_
|
|
40
44
|
*/
|
|
@@ -61,10 +65,27 @@ type ComparisonSorter<Item> = (first: Item, second: Item) => number;
|
|
|
61
65
|
* Direction to sort by
|
|
62
66
|
*/
|
|
63
67
|
type SortDirection = 'ascending' | 'descending';
|
|
68
|
+
type Sorter<Item> = (array: Item[]) => Item[];
|
|
64
69
|
/**
|
|
65
|
-
*
|
|
70
|
+
* Initialize a sort handler with sorters _(and an optional default direction)_
|
|
71
|
+
* @param sorters Sorters to use for sorting
|
|
72
|
+
* @param descending Sort in descending order? _(defaults to `false`; overridden by individual sorters)_
|
|
73
|
+
* @returns Sort handler
|
|
74
|
+
*/
|
|
75
|
+
declare function initializeSort<Item>(sorters: Array<ArraySorter<Item>>, descending?: boolean): Sorter<Item>;
|
|
76
|
+
/**
|
|
77
|
+
* Initialize a sort handler with a sorter _(and an optional default direction)_
|
|
78
|
+
* @param sorter Sorter to use for sorting
|
|
79
|
+
* @param descending Sort in descending order? _(defaults to `false`; overridden by individual sorters)_
|
|
80
|
+
* @returns Sort handler
|
|
81
|
+
*/
|
|
82
|
+
declare function initializeSort<Item>(sorter: ArraySorter<Item>, descending?: boolean): Sorter<Item>;
|
|
83
|
+
/**
|
|
84
|
+
* Initialize a sort handler _(with an optional default direction)_
|
|
85
|
+
* @param descending Sort in descending order? _(defaults to `false`)_
|
|
86
|
+
* @returns Sort handler
|
|
66
87
|
*/
|
|
67
|
-
|
|
88
|
+
declare function initializeSort<Item>(descending?: boolean): Sorter<Item>;
|
|
68
89
|
/**
|
|
69
90
|
* Sort an array of items, using multiple sorters to sort by specific values
|
|
70
91
|
* @param array Array to sort
|
|
@@ -72,7 +93,7 @@ type Sorter<Item> = Item extends PlainObject ? keyof Item | ArrayComparisonSorte
|
|
|
72
93
|
* @param descending Sort in descending order? _(defaults to `false`; overridden by individual sorters)_
|
|
73
94
|
* @returns Sorted array
|
|
74
95
|
*/
|
|
75
|
-
declare function sort<Item>(array: Item[], sorters: Array<
|
|
96
|
+
declare function sort<Item>(array: Item[], sorters: Array<ArraySorter<Item>>, descending?: boolean): Item[];
|
|
76
97
|
/**
|
|
77
98
|
* Sort an array of items, using multiple sorters to sort by specific values
|
|
78
99
|
* @param array Array to sort
|
|
@@ -80,7 +101,7 @@ declare function sort<Item>(array: Item[], sorters: Array<Sorter<Item>>, descend
|
|
|
80
101
|
* @param descending Sort in descending order? _(defaults to `false`; overridden by individual sorters)_
|
|
81
102
|
* @returns Sorted array
|
|
82
103
|
*/
|
|
83
|
-
declare function sort<Item>(array: Item[], sorter:
|
|
104
|
+
declare function sort<Item>(array: Item[], sorter: ArraySorter<Item>, descending?: boolean): Item[];
|
|
84
105
|
/**
|
|
85
106
|
* Sort an array of items
|
|
86
107
|
* @param array Array to sort
|
|
@@ -88,7 +109,10 @@ declare function sort<Item>(array: Item[], sorter: Sorter<Item>, descending?: bo
|
|
|
88
109
|
* @returns Sorted array
|
|
89
110
|
*/
|
|
90
111
|
declare function sort<Item>(array: Item[], descending?: boolean): Item[];
|
|
112
|
+
declare namespace sort {
|
|
113
|
+
var initialize: typeof initializeSort;
|
|
114
|
+
}
|
|
91
115
|
declare const SORT_DIRECTION_ASCENDING: SortDirection;
|
|
92
116
|
declare const SORT_DIRECTION_DESCENDING: SortDirection;
|
|
93
117
|
//#endregion
|
|
94
|
-
export { ArrayComparisonSorter, ArrayKeySorter, ArrayValueSorter, SORT_DIRECTION_ASCENDING, SORT_DIRECTION_DESCENDING, SortDirection, sort };
|
|
118
|
+
export { ArrayComparisonSorter, ArrayKeySorter, ArrayValueSorter, SORT_DIRECTION_ASCENDING, SORT_DIRECTION_DESCENDING, SortDirection, Sorter, sort };
|
package/dist/array/sort.mjs
CHANGED
|
@@ -9,6 +9,9 @@ function getComparisonSorter(callback, modifier) {
|
|
|
9
9
|
identifier: String(callback)
|
|
10
10
|
};
|
|
11
11
|
}
|
|
12
|
+
function getModifier(first, second) {
|
|
13
|
+
return modifiers[first === true || second === true ? SORT_DIRECTION_DESCENDING : SORT_DIRECTION_ASCENDING];
|
|
14
|
+
}
|
|
12
15
|
function getObjectSorter(obj, modifier) {
|
|
13
16
|
let sorter;
|
|
14
17
|
if (typeof obj.comparison === "function") sorter = getComparisonSorter(obj.comparison, modifier);
|
|
@@ -27,6 +30,17 @@ function getSorter(value, modifier) {
|
|
|
27
30
|
default: break;
|
|
28
31
|
}
|
|
29
32
|
}
|
|
33
|
+
function getSorters(value, modifier) {
|
|
34
|
+
const array = Array.isArray(value) ? value : [value];
|
|
35
|
+
const { length } = array;
|
|
36
|
+
const sorters = [];
|
|
37
|
+
for (let index = 0; index < length; index += 1) {
|
|
38
|
+
const item = array[index];
|
|
39
|
+
const sorter = getSorter(item, modifier);
|
|
40
|
+
if (sorter != null) sorters.push(sorter);
|
|
41
|
+
}
|
|
42
|
+
return sorters.filter((value, index, array) => array.findIndex((next) => next.identifier === value.identifier) === index);
|
|
43
|
+
}
|
|
30
44
|
function getValueSorter(value, modifier) {
|
|
31
45
|
return {
|
|
32
46
|
modifier,
|
|
@@ -35,32 +49,31 @@ function getValueSorter(value, modifier) {
|
|
|
35
49
|
value: typeof value === "function" ? value : (item) => item[value]
|
|
36
50
|
};
|
|
37
51
|
}
|
|
52
|
+
function initializeSort(first, second) {
|
|
53
|
+
const modifier = getModifier(first, second);
|
|
54
|
+
const sorters = getSorters(first, modifier);
|
|
55
|
+
return (array) => work(array, sorters, modifier);
|
|
56
|
+
}
|
|
38
57
|
function sort(array, first, second) {
|
|
58
|
+
const modifier = getModifier(first, second);
|
|
59
|
+
return work(array, getSorters(first, modifier), modifier);
|
|
60
|
+
}
|
|
61
|
+
function work(array, sorters, modifier) {
|
|
39
62
|
if (!Array.isArray(array)) return [];
|
|
40
63
|
if (array.length < 2) return array;
|
|
41
|
-
const modifier = modifiers[first === true || second === true ? SORT_DIRECTION_DESCENDING : SORT_DIRECTION_ASCENDING];
|
|
42
|
-
const sorters = (Array.isArray(first) ? first : [first]).map((item) => getSorter(item, modifier)).filter((sorter) => sorter != null).filter((current, index, filtered) => filtered.findIndex((next) => next.identifier === current.identifier) === index);
|
|
43
64
|
const { length } = sorters;
|
|
44
65
|
if (length === 0) return array.sort((first, second) => compare(first, second) * modifier);
|
|
45
|
-
|
|
46
|
-
const sorter = sorters[0];
|
|
47
|
-
return array.sort((firstItem, secondItem) => {
|
|
48
|
-
const firstValue = sorter.get ? sorter.value(firstItem) : firstItem;
|
|
49
|
-
const secondValue = sorter.get ? sorter.value(secondItem) : secondItem;
|
|
50
|
-
return (sorter.compare?.complex?.(firstItem, firstValue, secondItem, secondValue) ?? sorter.compare?.simple?.(firstItem, secondItem) ?? compare(firstValue, secondValue)) * sorter.modifier;
|
|
51
|
-
});
|
|
52
|
-
}
|
|
53
|
-
return array.sort((firstItem, secondItem) => {
|
|
66
|
+
return array.sort((first, second) => {
|
|
54
67
|
for (let index = 0; index < length; index += 1) {
|
|
55
68
|
const sorter = sorters[index];
|
|
56
|
-
const
|
|
57
|
-
const
|
|
58
|
-
const comparison = (sorter.compare?.complex?.(firstItem, firstValue, secondItem, secondValue) ?? sorter.compare?.simple?.(firstItem, secondItem) ?? compare(firstValue, secondValue)) * sorter.modifier;
|
|
69
|
+
const values = [sorter.get ? sorter.value(first) : first, sorter.get ? sorter.value(second) : second];
|
|
70
|
+
const comparison = (sorter.compare?.complex?.(first, values[0], second, values[1]) ?? sorter.compare?.simple?.(values[0], values[1]) ?? compare(values[0], values[1])) * sorter.modifier;
|
|
59
71
|
if (comparison !== 0) return comparison;
|
|
60
72
|
}
|
|
61
73
|
return 0;
|
|
62
74
|
});
|
|
63
75
|
}
|
|
76
|
+
sort.initialize = initializeSort;
|
|
64
77
|
const SORT_DIRECTION_ASCENDING = "ascending";
|
|
65
78
|
const SORT_DIRECTION_DESCENDING = "descending";
|
|
66
79
|
const modifiers = {
|
package/dist/index.d.mts
CHANGED
|
@@ -853,97 +853,6 @@ declare function take<Item extends PlainObject>(array: Item[], callback: (item:
|
|
|
853
853
|
*/
|
|
854
854
|
declare function take(array: unknown[], count: number): unknown[];
|
|
855
855
|
//#endregion
|
|
856
|
-
//#region src/array/sort.d.ts
|
|
857
|
-
/**
|
|
858
|
-
* Sorting information for arrays _(using a comparison callback)_
|
|
859
|
-
*/
|
|
860
|
-
type ArrayComparisonSorter<Item> = {
|
|
861
|
-
/**
|
|
862
|
-
* Callback to use when comparing items and values
|
|
863
|
-
*/
|
|
864
|
-
comparison: ComparisonSorter<Item>;
|
|
865
|
-
/**
|
|
866
|
-
* Direction to sort by
|
|
867
|
-
*/
|
|
868
|
-
direction?: SortDirection;
|
|
869
|
-
};
|
|
870
|
-
/**
|
|
871
|
-
* Sorting information for arrays _(using a key)_
|
|
872
|
-
*/
|
|
873
|
-
type ArrayKeySorter<Item extends PlainObject, ItemKey extends keyof Item> = {
|
|
874
|
-
/**
|
|
875
|
-
* Comparator to use when comparing items and values
|
|
876
|
-
*/
|
|
877
|
-
compare?: CompareCallback<Item, Item[ItemKey]>;
|
|
878
|
-
/**
|
|
879
|
-
* Direction to sort by
|
|
880
|
-
*/
|
|
881
|
-
direction?: SortDirection;
|
|
882
|
-
/**
|
|
883
|
-
* Key to sort by
|
|
884
|
-
*/
|
|
885
|
-
key: ItemKey;
|
|
886
|
-
};
|
|
887
|
-
/**
|
|
888
|
-
* Sorters based on keys in an object
|
|
889
|
-
*/
|
|
890
|
-
type ArrayKeySorters<Item extends PlainObject> = { [ItemKey in keyof Item]: ArrayKeySorter<Item, ItemKey> }[keyof Item];
|
|
891
|
-
/**
|
|
892
|
-
* Sorting information for arrays _(using a value callback and built-in comparison)_
|
|
893
|
-
*/
|
|
894
|
-
type ArrayValueSorter<Item> = {
|
|
895
|
-
/**
|
|
896
|
-
* Direction to sort by
|
|
897
|
-
*/
|
|
898
|
-
direction?: SortDirection;
|
|
899
|
-
/**
|
|
900
|
-
* Value to sort by
|
|
901
|
-
*/
|
|
902
|
-
value: (item: Item) => unknown;
|
|
903
|
-
};
|
|
904
|
-
/**
|
|
905
|
-
* Comparator to use when comparing items and values
|
|
906
|
-
*/
|
|
907
|
-
type CompareCallback<Item, Value = CompareCallbackValue<Item>> = (first: Item, firstValue: Value, second: Item, secondValue: Value) => number;
|
|
908
|
-
type CompareCallbackValue<Item> = Item extends Primitive ? Item : unknown;
|
|
909
|
-
/**
|
|
910
|
-
* Callback to use when comparing items and values
|
|
911
|
-
*/
|
|
912
|
-
type ComparisonSorter<Item> = (first: Item, second: Item) => number;
|
|
913
|
-
/**
|
|
914
|
-
* Direction to sort by
|
|
915
|
-
*/
|
|
916
|
-
type SortDirection = 'ascending' | 'descending';
|
|
917
|
-
/**
|
|
918
|
-
* Sorter to use for sorting
|
|
919
|
-
*/
|
|
920
|
-
type Sorter<Item> = Item extends PlainObject ? keyof Item | ArrayComparisonSorter<Item> | ArrayKeySorters<Item> | ArrayValueSorter<Item> | ComparisonSorter<Item> : ArrayComparisonSorter<Item> | ArrayValueSorter<Item> | ComparisonSorter<Item>;
|
|
921
|
-
/**
|
|
922
|
-
* Sort an array of items, using multiple sorters to sort by specific values
|
|
923
|
-
* @param array Array to sort
|
|
924
|
-
* @param sorters Sorters to use for sorting
|
|
925
|
-
* @param descending Sort in descending order? _(defaults to `false`; overridden by individual sorters)_
|
|
926
|
-
* @returns Sorted array
|
|
927
|
-
*/
|
|
928
|
-
declare function sort<Item>(array: Item[], sorters: Array<Sorter<Item>>, descending?: boolean): Item[];
|
|
929
|
-
/**
|
|
930
|
-
* Sort an array of items, using multiple sorters to sort by specific values
|
|
931
|
-
* @param array Array to sort
|
|
932
|
-
* @param sorter Sorter to use for sorting
|
|
933
|
-
* @param descending Sort in descending order? _(defaults to `false`; overridden by individual sorters)_
|
|
934
|
-
* @returns Sorted array
|
|
935
|
-
*/
|
|
936
|
-
declare function sort<Item>(array: Item[], sorter: Sorter<Item>, descending?: boolean): Item[];
|
|
937
|
-
/**
|
|
938
|
-
* Sort an array of items
|
|
939
|
-
* @param array Array to sort
|
|
940
|
-
* @param descending Sort in descending order? _(defaults to `false`)_
|
|
941
|
-
* @returns Sorted array
|
|
942
|
-
*/
|
|
943
|
-
declare function sort<Item>(array: Item[], descending?: boolean): Item[];
|
|
944
|
-
declare const SORT_DIRECTION_ASCENDING: SortDirection;
|
|
945
|
-
declare const SORT_DIRECTION_DESCENDING: SortDirection;
|
|
946
|
-
//#endregion
|
|
947
856
|
//#region src/array/splice.d.ts
|
|
948
857
|
/**
|
|
949
858
|
* Adds items into an array at a specific index and removes a specific amount of items
|
|
@@ -1183,6 +1092,121 @@ declare function moveToIndex<Item>(array: Item[], value: Item | Item[], index: n
|
|
|
1183
1092
|
*/
|
|
1184
1093
|
declare function moveToIndex<Item>(array: Item[], value: Item | Item[], index: number): Item[];
|
|
1185
1094
|
//#endregion
|
|
1095
|
+
//#region src/array/sort.d.ts
|
|
1096
|
+
/**
|
|
1097
|
+
* Sorting information for arrays _(using a comparison callback)_
|
|
1098
|
+
*/
|
|
1099
|
+
type ArrayComparisonSorter<Item> = {
|
|
1100
|
+
/**
|
|
1101
|
+
* Callback to use when comparing items and values
|
|
1102
|
+
*/
|
|
1103
|
+
comparison: ComparisonSorter<Item>;
|
|
1104
|
+
/**
|
|
1105
|
+
* Direction to sort by
|
|
1106
|
+
*/
|
|
1107
|
+
direction?: SortDirection;
|
|
1108
|
+
};
|
|
1109
|
+
/**
|
|
1110
|
+
* Sorting information for arrays _(using a key)_
|
|
1111
|
+
*/
|
|
1112
|
+
type ArrayKeySorter<Item extends PlainObject, ItemKey extends keyof Item> = {
|
|
1113
|
+
/**
|
|
1114
|
+
* Comparator to use when comparing items and values
|
|
1115
|
+
*/
|
|
1116
|
+
compare?: CompareCallback<Item, Item[ItemKey]>;
|
|
1117
|
+
/**
|
|
1118
|
+
* Direction to sort by
|
|
1119
|
+
*/
|
|
1120
|
+
direction?: SortDirection;
|
|
1121
|
+
/**
|
|
1122
|
+
* Key to sort by
|
|
1123
|
+
*/
|
|
1124
|
+
key: ItemKey;
|
|
1125
|
+
};
|
|
1126
|
+
/**
|
|
1127
|
+
* Sorters based on keys in an object
|
|
1128
|
+
*/
|
|
1129
|
+
type ArrayKeySorters<Item extends PlainObject> = { [ItemKey in keyof Item]: ArrayKeySorter<Item, ItemKey> }[keyof Item];
|
|
1130
|
+
/**
|
|
1131
|
+
* Sorter to use for sorting
|
|
1132
|
+
*/
|
|
1133
|
+
type ArraySorter<Item> = Item extends PlainObject ? keyof Item | ArrayComparisonSorter<Item> | ArrayKeySorters<Item> | ArrayValueSorter<Item> | ComparisonSorter<Item> : ArrayComparisonSorter<Item> | ArrayValueSorter<Item> | ComparisonSorter<Item>;
|
|
1134
|
+
/**
|
|
1135
|
+
* Sorting information for arrays _(using a value callback and built-in comparison)_
|
|
1136
|
+
*/
|
|
1137
|
+
type ArrayValueSorter<Item> = {
|
|
1138
|
+
/**
|
|
1139
|
+
* Direction to sort by
|
|
1140
|
+
*/
|
|
1141
|
+
direction?: SortDirection;
|
|
1142
|
+
/**
|
|
1143
|
+
* Value to sort by
|
|
1144
|
+
*/
|
|
1145
|
+
value: (item: Item) => unknown;
|
|
1146
|
+
};
|
|
1147
|
+
/**
|
|
1148
|
+
* Comparator to use when comparing items and values
|
|
1149
|
+
*/
|
|
1150
|
+
type CompareCallback<Item, Value = CompareCallbackValue<Item>> = (first: Item, firstValue: Value, second: Item, secondValue: Value) => number;
|
|
1151
|
+
type CompareCallbackValue<Item> = Item extends Primitive ? Item : unknown;
|
|
1152
|
+
/**
|
|
1153
|
+
* Callback to use when comparing items and values
|
|
1154
|
+
*/
|
|
1155
|
+
type ComparisonSorter<Item> = (first: Item, second: Item) => number;
|
|
1156
|
+
/**
|
|
1157
|
+
* Direction to sort by
|
|
1158
|
+
*/
|
|
1159
|
+
type SortDirection = 'ascending' | 'descending';
|
|
1160
|
+
type Sorter<Item> = (array: Item[]) => Item[];
|
|
1161
|
+
/**
|
|
1162
|
+
* Initialize a sort handler with sorters _(and an optional default direction)_
|
|
1163
|
+
* @param sorters Sorters to use for sorting
|
|
1164
|
+
* @param descending Sort in descending order? _(defaults to `false`; overridden by individual sorters)_
|
|
1165
|
+
* @returns Sort handler
|
|
1166
|
+
*/
|
|
1167
|
+
declare function initializeSort<Item>(sorters: Array<ArraySorter<Item>>, descending?: boolean): Sorter<Item>;
|
|
1168
|
+
/**
|
|
1169
|
+
* Initialize a sort handler with a sorter _(and an optional default direction)_
|
|
1170
|
+
* @param sorter Sorter to use for sorting
|
|
1171
|
+
* @param descending Sort in descending order? _(defaults to `false`; overridden by individual sorters)_
|
|
1172
|
+
* @returns Sort handler
|
|
1173
|
+
*/
|
|
1174
|
+
declare function initializeSort<Item>(sorter: ArraySorter<Item>, descending?: boolean): Sorter<Item>;
|
|
1175
|
+
/**
|
|
1176
|
+
* Initialize a sort handler _(with an optional default direction)_
|
|
1177
|
+
* @param descending Sort in descending order? _(defaults to `false`)_
|
|
1178
|
+
* @returns Sort handler
|
|
1179
|
+
*/
|
|
1180
|
+
declare function initializeSort<Item>(descending?: boolean): Sorter<Item>;
|
|
1181
|
+
/**
|
|
1182
|
+
* Sort an array of items, using multiple sorters to sort by specific values
|
|
1183
|
+
* @param array Array to sort
|
|
1184
|
+
* @param sorters Sorters to use for sorting
|
|
1185
|
+
* @param descending Sort in descending order? _(defaults to `false`; overridden by individual sorters)_
|
|
1186
|
+
* @returns Sorted array
|
|
1187
|
+
*/
|
|
1188
|
+
declare function sort<Item>(array: Item[], sorters: Array<ArraySorter<Item>>, descending?: boolean): Item[];
|
|
1189
|
+
/**
|
|
1190
|
+
* Sort an array of items, using multiple sorters to sort by specific values
|
|
1191
|
+
* @param array Array to sort
|
|
1192
|
+
* @param sorter Sorter to use for sorting
|
|
1193
|
+
* @param descending Sort in descending order? _(defaults to `false`; overridden by individual sorters)_
|
|
1194
|
+
* @returns Sorted array
|
|
1195
|
+
*/
|
|
1196
|
+
declare function sort<Item>(array: Item[], sorter: ArraySorter<Item>, descending?: boolean): Item[];
|
|
1197
|
+
/**
|
|
1198
|
+
* Sort an array of items
|
|
1199
|
+
* @param array Array to sort
|
|
1200
|
+
* @param descending Sort in descending order? _(defaults to `false`)_
|
|
1201
|
+
* @returns Sorted array
|
|
1202
|
+
*/
|
|
1203
|
+
declare function sort<Item>(array: Item[], descending?: boolean): Item[];
|
|
1204
|
+
declare namespace sort {
|
|
1205
|
+
var initialize: typeof initializeSort;
|
|
1206
|
+
}
|
|
1207
|
+
declare const SORT_DIRECTION_ASCENDING: SortDirection;
|
|
1208
|
+
declare const SORT_DIRECTION_DESCENDING: SortDirection;
|
|
1209
|
+
//#endregion
|
|
1186
1210
|
//#region src/array/swap.d.ts
|
|
1187
1211
|
/**
|
|
1188
1212
|
* Swap two smaller arrays within a larger array
|
|
@@ -4327,4 +4351,4 @@ declare class SizedSet<Value = unknown> extends Set<Value> {
|
|
|
4327
4351
|
get(value: Value, update?: boolean): Value | undefined;
|
|
4328
4352
|
}
|
|
4329
4353
|
//#endregion
|
|
4330
|
-
export { AnyResult, ArrayComparisonSorter, ArrayKeySorter, ArrayOrPlainObject, ArrayPosition, ArrayValueSorter, Asserter, AttemptFlow, AttemptFlowPromise, type Beacon, type BeaconOptions, BuiltIns, CancelableCallback, CancelablePromise, type Color, Constructor, DiffOptions, DiffResult, DiffValue, EqualOptions, Err, EventPosition, ExtendedErr, ExtendedResult, Flow, FlowPromise, FulfilledPromise, GenericAsyncCallback, GenericCallback, type HSLAColor, type HSLColor, HasValue, Key, KeyedValue, type Logger, type Memoized, type MemoizedOptions, MergeOptions, Merger, NestedArray, NestedKeys, NestedPartial, NestedValue, NestedValues, NumericalKeys, NumericalValues, type Observable, type Observer, Ok, OnceAsyncCallback, OnceCallback, PROMISE_ABORT_EVENT, PROMISE_ABORT_OPTIONS, PROMISE_ERROR_NAME, PROMISE_MESSAGE_EXPECTATION_ATTEMPT, PROMISE_MESSAGE_EXPECTATION_RESULT, PROMISE_MESSAGE_EXPECTATION_TIMED, PROMISE_MESSAGE_TIMEOUT, PROMISE_STRATEGY_ALL, PROMISE_STRATEGY_DEFAULT, PROMISE_TYPE_FULFILLED, PROMISE_TYPE_REJECTED, PlainObject, Primitive, PromiseData, PromiseHandlers, PromiseOptions, PromiseParameters, PromiseStrategy, PromiseTimeoutError, PromisesItems, PromisesOptions, PromisesResult, PromisesUnwrapped, PromisesValue, PromisesValues, type Queue, QueueError, type QueueOptions, type Queued, type RGBAColor, type RGBColor, RejectedPromise, RequiredKeys, Result, ResultMatch, RetryError, RetryOptions, SORT_DIRECTION_ASCENDING, SORT_DIRECTION_DESCENDING, Simplify, SizedMap, SizedSet, Smushed, SortDirection, type Subscription, TemplateOptions, type Time, ToString, TypedArray, Unsmushed, UnwrapValue, assert, attempt, attemptFlow, attemptPipe, attemptPromise, average, beacon, between, camelCase, cancelable, capitalize, ceil, chunk, clamp, clone, compact, compare, count, debounce, delay, diff, difference, drop, endsWith, endsWithArray, equal, error, exists, filter, find, flatten, floor, flow, fromQuery, toPromise as fromResult, toPromise, getArray, getArrayPosition, getColor, getError, getForegroundColor, getHexColor, getHexaColor, getHslColor, getHslaColor, getNormalizedHex, getNumber, getRandomBoolean, getRandomCharacters, getRandomColor, getRandomFloat, getRandomHex, getRandomInteger, getRandomItem, getRandomItems, getRgbColor, getRgbaColor, getString, getTimedPromise, getUuid, getValue, groupBy, handleResult, hasValue, hexToHsl, hexToHsla, hexToRgb, hexToRgba, hslToHex, hslToRgb, hslToRgba, ignoreKey, includes, includesArray, indexOf, indexOfArray, insert, intersection, isArrayOrPlainObject, isColor, isConstructor, isEmpty, isError, isFulfilled, isHexColor, isHslColor, isHslLike, isHslaColor, isInstanceOf, isKey, isNonNullable, isNullable, isNullableOrEmpty, isNullableOrWhitespace, isNumber, isNumerical, isObject, isOk, isPlainObject, isPrimitive, isRejected, isResult, isRgbColor, isRgbLike, isRgbaColor, isTypedArray, join, kebabCase, logger, lowerCase, matchResult, max, median, memoize, merge, min, move, noop, ok, omit, once, parse, partition, pascalCase, pick, pipe, promises, push, queue, range, retry, rgbToHex, rgbToHsl, rgbToHsla, round, select, setValue, settlePromise, shuffle, slice, smush, snakeCase, sort, splice, startsWith, startsWithArray, sum, swap, take, template, throttle, timed, times, titleCase, toMap, toQuery, toRecord, toResult, toSet, toggle, trim, truncate, tryDecode, tryEncode, union, unique, unsmush, unwrap, update, upperCase, words };
|
|
4354
|
+
export { AnyResult, ArrayComparisonSorter, ArrayKeySorter, ArrayOrPlainObject, ArrayPosition, ArrayValueSorter, Asserter, AttemptFlow, AttemptFlowPromise, type Beacon, type BeaconOptions, BuiltIns, CancelableCallback, CancelablePromise, type Color, Constructor, DiffOptions, DiffResult, DiffValue, EqualOptions, Err, EventPosition, ExtendedErr, ExtendedResult, Flow, FlowPromise, FulfilledPromise, GenericAsyncCallback, GenericCallback, type HSLAColor, type HSLColor, HasValue, Key, KeyedValue, type Logger, type Memoized, type MemoizedOptions, MergeOptions, Merger, NestedArray, NestedKeys, NestedPartial, NestedValue, NestedValues, NumericalKeys, NumericalValues, type Observable, type Observer, Ok, OnceAsyncCallback, OnceCallback, PROMISE_ABORT_EVENT, PROMISE_ABORT_OPTIONS, PROMISE_ERROR_NAME, PROMISE_MESSAGE_EXPECTATION_ATTEMPT, PROMISE_MESSAGE_EXPECTATION_RESULT, PROMISE_MESSAGE_EXPECTATION_TIMED, PROMISE_MESSAGE_TIMEOUT, PROMISE_STRATEGY_ALL, PROMISE_STRATEGY_DEFAULT, PROMISE_TYPE_FULFILLED, PROMISE_TYPE_REJECTED, PlainObject, Primitive, PromiseData, PromiseHandlers, PromiseOptions, PromiseParameters, PromiseStrategy, PromiseTimeoutError, PromisesItems, PromisesOptions, PromisesResult, PromisesUnwrapped, PromisesValue, PromisesValues, type Queue, QueueError, type QueueOptions, type Queued, type RGBAColor, type RGBColor, RejectedPromise, RequiredKeys, Result, ResultMatch, RetryError, RetryOptions, SORT_DIRECTION_ASCENDING, SORT_DIRECTION_DESCENDING, Simplify, SizedMap, SizedSet, Smushed, SortDirection, Sorter, type Subscription, TemplateOptions, type Time, ToString, TypedArray, Unsmushed, UnwrapValue, assert, attempt, attemptFlow, attemptPipe, attemptPromise, average, beacon, between, camelCase, cancelable, capitalize, ceil, chunk, clamp, clone, compact, compare, count, debounce, delay, diff, difference, drop, endsWith, endsWithArray, equal, error, exists, filter, find, flatten, floor, flow, fromQuery, toPromise as fromResult, toPromise, getArray, getArrayPosition, getColor, getError, getForegroundColor, getHexColor, getHexaColor, getHslColor, getHslaColor, getNormalizedHex, getNumber, getRandomBoolean, getRandomCharacters, getRandomColor, getRandomFloat, getRandomHex, getRandomInteger, getRandomItem, getRandomItems, getRgbColor, getRgbaColor, getString, getTimedPromise, getUuid, getValue, groupBy, handleResult, hasValue, hexToHsl, hexToHsla, hexToRgb, hexToRgba, hslToHex, hslToRgb, hslToRgba, ignoreKey, includes, includesArray, indexOf, indexOfArray, insert, intersection, isArrayOrPlainObject, isColor, isConstructor, isEmpty, isError, isFulfilled, isHexColor, isHslColor, isHslLike, isHslaColor, isInstanceOf, isKey, isNonNullable, isNullable, isNullableOrEmpty, isNullableOrWhitespace, isNumber, isNumerical, isObject, isOk, isPlainObject, isPrimitive, isRejected, isResult, isRgbColor, isRgbLike, isRgbaColor, isTypedArray, join, kebabCase, logger, lowerCase, matchResult, max, median, memoize, merge, min, move, noop, ok, omit, once, parse, partition, pascalCase, pick, pipe, promises, push, queue, range, retry, rgbToHex, rgbToHsl, rgbToHsla, round, select, setValue, settlePromise, shuffle, slice, smush, snakeCase, sort, splice, startsWith, startsWithArray, sum, swap, take, template, throttle, timed, times, titleCase, toMap, toQuery, toRecord, toResult, toSet, toggle, trim, truncate, tryDecode, tryEncode, union, unique, unsmush, unwrap, update, upperCase, words };
|
package/dist/index.mjs
CHANGED
|
@@ -538,6 +538,146 @@ function take(array, first, second) {
|
|
|
538
538
|
const EXTRACT_DROP = "drop";
|
|
539
539
|
const EXTRACT_TAKE = "take";
|
|
540
540
|
//#endregion
|
|
541
|
+
//#region src/array/splice.ts
|
|
542
|
+
function splice(array, start, deleteCountOrItems, items) {
|
|
543
|
+
return insertValues(INSERT_TYPE_SPLICE, array, typeof deleteCountOrItems === "number" ? items : deleteCountOrItems, start, typeof deleteCountOrItems === "number" ? deleteCountOrItems : 0);
|
|
544
|
+
}
|
|
545
|
+
//#endregion
|
|
546
|
+
//#region src/array/to-set.ts
|
|
547
|
+
function toSet(array, value) {
|
|
548
|
+
if (!Array.isArray(array)) return /* @__PURE__ */ new Set();
|
|
549
|
+
const callbacks = getArrayCallbacks(void 0, void 0, value);
|
|
550
|
+
if (callbacks?.value == null) return new Set(array);
|
|
551
|
+
const { length } = array;
|
|
552
|
+
const set = /* @__PURE__ */ new Set();
|
|
553
|
+
for (let index = 0; index < length; index += 1) set.add(callbacks.value(array[index], index, array));
|
|
554
|
+
return set;
|
|
555
|
+
}
|
|
556
|
+
//#endregion
|
|
557
|
+
//#region src/internal/array/update.ts
|
|
558
|
+
function updateInArray(array, items, key, replace) {
|
|
559
|
+
if (!Array.isArray(array)) return [];
|
|
560
|
+
const itemsIsArray = Array.isArray(items);
|
|
561
|
+
if (array.length === 0 || !itemsIsArray) {
|
|
562
|
+
if (itemsIsArray) array.push(...items);
|
|
563
|
+
return array;
|
|
564
|
+
}
|
|
565
|
+
const { length } = items;
|
|
566
|
+
if (length === 0) return array;
|
|
567
|
+
const callback = getArrayCallback(key);
|
|
568
|
+
for (let valuesIndex = 0; valuesIndex < length; valuesIndex += 1) {
|
|
569
|
+
const item = items[valuesIndex];
|
|
570
|
+
const value = callback?.(item) ?? item;
|
|
571
|
+
const arrayIndex = callback == null ? array.indexOf(value) : array.findIndex((arrayItem, arrayIndex) => callback(arrayItem, arrayIndex, array) === value);
|
|
572
|
+
if (arrayIndex === -1) array.push(item);
|
|
573
|
+
else if (replace) array[arrayIndex] = item;
|
|
574
|
+
else array.splice(arrayIndex, 1);
|
|
575
|
+
}
|
|
576
|
+
return array;
|
|
577
|
+
}
|
|
578
|
+
//#endregion
|
|
579
|
+
//#region src/array/toggle.ts
|
|
580
|
+
function toggle(array, values, key) {
|
|
581
|
+
return updateInArray(array, values, key, false);
|
|
582
|
+
}
|
|
583
|
+
//#endregion
|
|
584
|
+
//#region src/array/union.ts
|
|
585
|
+
function union(first, second, key) {
|
|
586
|
+
return compareSets(COMPARE_SETS_UNION, first, second, key);
|
|
587
|
+
}
|
|
588
|
+
//#endregion
|
|
589
|
+
//#region src/array/unique.ts
|
|
590
|
+
function unique(array, key) {
|
|
591
|
+
if (!Array.isArray(array)) return [];
|
|
592
|
+
return array.length > 1 ? findValues(FIND_VALUES_UNIQUE, array, [key, void 0]).matched : array;
|
|
593
|
+
}
|
|
594
|
+
//#endregion
|
|
595
|
+
//#region src/array/update.ts
|
|
596
|
+
function update(array, values, key) {
|
|
597
|
+
return updateInArray(array, values, key, true);
|
|
598
|
+
}
|
|
599
|
+
//#endregion
|
|
600
|
+
//#region src/internal/array/overlap.ts
|
|
601
|
+
function arraysOverlap(first, second) {
|
|
602
|
+
const firstArray = first.index < second.index ? first.array : second.array;
|
|
603
|
+
const secondArray = first.index < second.index ? second.array : first.array;
|
|
604
|
+
const firstIndex = firstArray === first.array ? first.index : second.index;
|
|
605
|
+
const secondIndex = firstArray === first.array ? second.index : first.index;
|
|
606
|
+
const firstEnd = firstIndex + firstArray.length - 1;
|
|
607
|
+
return {
|
|
608
|
+
overlap: firstIndex <= secondIndex + secondArray.length - 1 && firstEnd >= secondIndex,
|
|
609
|
+
first: {
|
|
610
|
+
array: firstArray,
|
|
611
|
+
index: firstIndex
|
|
612
|
+
},
|
|
613
|
+
second: {
|
|
614
|
+
array: secondArray,
|
|
615
|
+
index: secondIndex
|
|
616
|
+
}
|
|
617
|
+
};
|
|
618
|
+
}
|
|
619
|
+
//#endregion
|
|
620
|
+
//#region src/array/move.ts
|
|
621
|
+
function move(array, from, to, key) {
|
|
622
|
+
if (!Array.isArray(array)) return [];
|
|
623
|
+
const firstArray = Array.isArray(from) ? from : [from];
|
|
624
|
+
const secondArray = Array.isArray(to) ? to : [to];
|
|
625
|
+
if (firstArray.length === 0 || secondArray.length === 0) return array;
|
|
626
|
+
const firstPosition = indexOfArray(array, firstArray, key);
|
|
627
|
+
const secondPosition = indexOfArray(array, secondArray, key);
|
|
628
|
+
if (firstPosition === -1 || secondPosition === -1 || firstPosition === secondPosition) return array;
|
|
629
|
+
const { overlap } = arraysOverlap({
|
|
630
|
+
array: firstArray,
|
|
631
|
+
index: firstPosition
|
|
632
|
+
}, {
|
|
633
|
+
array: secondArray,
|
|
634
|
+
index: secondPosition
|
|
635
|
+
});
|
|
636
|
+
if (overlap) return array;
|
|
637
|
+
array.splice(firstPosition, firstArray.length);
|
|
638
|
+
const next = secondPosition < firstPosition ? secondPosition : secondPosition + secondArray.length - firstArray.length;
|
|
639
|
+
if (next >= array.length) array.push(...firstArray);
|
|
640
|
+
else array.splice(next, 0, ...firstArray);
|
|
641
|
+
return array;
|
|
642
|
+
}
|
|
643
|
+
move.indices = moveIndices;
|
|
644
|
+
move.toIndex = moveToIndex;
|
|
645
|
+
/**
|
|
646
|
+
* Move an item from one index to another within an array
|
|
647
|
+
*
|
|
648
|
+
* If the from index is out of bounds, the array will be returned unchanged
|
|
649
|
+
* @param array Array to move within
|
|
650
|
+
* @param from Index to move from
|
|
651
|
+
* @param to Index to move to
|
|
652
|
+
* @returns Original array with item moved _(or unchanged if unable to move)_
|
|
653
|
+
*/
|
|
654
|
+
function moveIndices(array, from, to) {
|
|
655
|
+
if (!Array.isArray(array)) return [];
|
|
656
|
+
const { length } = array;
|
|
657
|
+
if (length === 0 || typeof from !== "number" || typeof to !== "number") return array;
|
|
658
|
+
const fromIndex = from < 0 ? length + from : from;
|
|
659
|
+
const toIndex = to < 0 ? length + to : to;
|
|
660
|
+
if (fromIndex === toIndex || fromIndex >= length || toIndex >= length) return array;
|
|
661
|
+
const spliced = array.splice(fromIndex, 1);
|
|
662
|
+
if (toIndex >= array.length) array.push(...spliced);
|
|
663
|
+
else array.splice(toIndex, 0, ...spliced);
|
|
664
|
+
return array;
|
|
665
|
+
}
|
|
666
|
+
function moveToIndex(array, value, index, key) {
|
|
667
|
+
if (!Array.isArray(array)) return [];
|
|
668
|
+
const { length } = array;
|
|
669
|
+
if (length === 0 || typeof index !== "number") return array;
|
|
670
|
+
const next = index < 0 ? length + index : index;
|
|
671
|
+
if (next >= length) return array;
|
|
672
|
+
const values = Array.isArray(value) ? value : [value];
|
|
673
|
+
const position = indexOfArray(array, values, key);
|
|
674
|
+
if (position === -1 || position === next) return array;
|
|
675
|
+
array.splice(position, values.length);
|
|
676
|
+
if (next >= array.length) array.push(...values);
|
|
677
|
+
else array.splice(next, 0, ...values);
|
|
678
|
+
return array;
|
|
679
|
+
}
|
|
680
|
+
//#endregion
|
|
541
681
|
//#region src/internal/math/aggregate.ts
|
|
542
682
|
function aggregate(type, array, key) {
|
|
543
683
|
const length = Array.isArray(array) ? array.length : 0;
|
|
@@ -770,6 +910,9 @@ function getComparisonSorter(callback, modifier) {
|
|
|
770
910
|
identifier: String(callback)
|
|
771
911
|
};
|
|
772
912
|
}
|
|
913
|
+
function getModifier(first, second) {
|
|
914
|
+
return modifiers[first === true || second === true ? SORT_DIRECTION_DESCENDING : SORT_DIRECTION_ASCENDING];
|
|
915
|
+
}
|
|
773
916
|
function getObjectSorter(obj, modifier) {
|
|
774
917
|
let sorter;
|
|
775
918
|
if (typeof obj.comparison === "function") sorter = getComparisonSorter(obj.comparison, modifier);
|
|
@@ -788,6 +931,17 @@ function getSorter(value, modifier) {
|
|
|
788
931
|
default: break;
|
|
789
932
|
}
|
|
790
933
|
}
|
|
934
|
+
function getSorters(value, modifier) {
|
|
935
|
+
const array = Array.isArray(value) ? value : [value];
|
|
936
|
+
const { length } = array;
|
|
937
|
+
const sorters = [];
|
|
938
|
+
for (let index = 0; index < length; index += 1) {
|
|
939
|
+
const item = array[index];
|
|
940
|
+
const sorter = getSorter(item, modifier);
|
|
941
|
+
if (sorter != null) sorters.push(sorter);
|
|
942
|
+
}
|
|
943
|
+
return sorters.filter((value, index, array) => array.findIndex((next) => next.identifier === value.identifier) === index);
|
|
944
|
+
}
|
|
791
945
|
function getValueSorter(value, modifier) {
|
|
792
946
|
return {
|
|
793
947
|
modifier,
|
|
@@ -796,32 +950,31 @@ function getValueSorter(value, modifier) {
|
|
|
796
950
|
value: typeof value === "function" ? value : (item) => item[value]
|
|
797
951
|
};
|
|
798
952
|
}
|
|
953
|
+
function initializeSort(first, second) {
|
|
954
|
+
const modifier = getModifier(first, second);
|
|
955
|
+
const sorters = getSorters(first, modifier);
|
|
956
|
+
return (array) => work$1(array, sorters, modifier);
|
|
957
|
+
}
|
|
799
958
|
function sort(array, first, second) {
|
|
959
|
+
const modifier = getModifier(first, second);
|
|
960
|
+
return work$1(array, getSorters(first, modifier), modifier);
|
|
961
|
+
}
|
|
962
|
+
function work$1(array, sorters, modifier) {
|
|
800
963
|
if (!Array.isArray(array)) return [];
|
|
801
964
|
if (array.length < 2) return array;
|
|
802
|
-
const modifier = modifiers[first === true || second === true ? SORT_DIRECTION_DESCENDING : SORT_DIRECTION_ASCENDING];
|
|
803
|
-
const sorters = (Array.isArray(first) ? first : [first]).map((item) => getSorter(item, modifier)).filter((sorter) => sorter != null).filter((current, index, filtered) => filtered.findIndex((next) => next.identifier === current.identifier) === index);
|
|
804
965
|
const { length } = sorters;
|
|
805
966
|
if (length === 0) return array.sort((first, second) => compare(first, second) * modifier);
|
|
806
|
-
|
|
807
|
-
const sorter = sorters[0];
|
|
808
|
-
return array.sort((firstItem, secondItem) => {
|
|
809
|
-
const firstValue = sorter.get ? sorter.value(firstItem) : firstItem;
|
|
810
|
-
const secondValue = sorter.get ? sorter.value(secondItem) : secondItem;
|
|
811
|
-
return (sorter.compare?.complex?.(firstItem, firstValue, secondItem, secondValue) ?? sorter.compare?.simple?.(firstItem, secondItem) ?? compare(firstValue, secondValue)) * sorter.modifier;
|
|
812
|
-
});
|
|
813
|
-
}
|
|
814
|
-
return array.sort((firstItem, secondItem) => {
|
|
967
|
+
return array.sort((first, second) => {
|
|
815
968
|
for (let index = 0; index < length; index += 1) {
|
|
816
969
|
const sorter = sorters[index];
|
|
817
|
-
const
|
|
818
|
-
const
|
|
819
|
-
const comparison = (sorter.compare?.complex?.(firstItem, firstValue, secondItem, secondValue) ?? sorter.compare?.simple?.(firstItem, secondItem) ?? compare(firstValue, secondValue)) * sorter.modifier;
|
|
970
|
+
const values = [sorter.get ? sorter.value(first) : first, sorter.get ? sorter.value(second) : second];
|
|
971
|
+
const comparison = (sorter.compare?.complex?.(first, values[0], second, values[1]) ?? sorter.compare?.simple?.(values[0], values[1]) ?? compare(values[0], values[1])) * sorter.modifier;
|
|
820
972
|
if (comparison !== 0) return comparison;
|
|
821
973
|
}
|
|
822
974
|
return 0;
|
|
823
975
|
});
|
|
824
976
|
}
|
|
977
|
+
sort.initialize = initializeSort;
|
|
825
978
|
const SORT_DIRECTION_ASCENDING = "ascending";
|
|
826
979
|
const SORT_DIRECTION_DESCENDING = "descending";
|
|
827
980
|
const modifiers = {
|
|
@@ -829,146 +982,6 @@ const modifiers = {
|
|
|
829
982
|
[SORT_DIRECTION_DESCENDING]: -1
|
|
830
983
|
};
|
|
831
984
|
//#endregion
|
|
832
|
-
//#region src/array/splice.ts
|
|
833
|
-
function splice(array, start, deleteCountOrItems, items) {
|
|
834
|
-
return insertValues(INSERT_TYPE_SPLICE, array, typeof deleteCountOrItems === "number" ? items : deleteCountOrItems, start, typeof deleteCountOrItems === "number" ? deleteCountOrItems : 0);
|
|
835
|
-
}
|
|
836
|
-
//#endregion
|
|
837
|
-
//#region src/array/to-set.ts
|
|
838
|
-
function toSet(array, value) {
|
|
839
|
-
if (!Array.isArray(array)) return /* @__PURE__ */ new Set();
|
|
840
|
-
const callbacks = getArrayCallbacks(void 0, void 0, value);
|
|
841
|
-
if (callbacks?.value == null) return new Set(array);
|
|
842
|
-
const { length } = array;
|
|
843
|
-
const set = /* @__PURE__ */ new Set();
|
|
844
|
-
for (let index = 0; index < length; index += 1) set.add(callbacks.value(array[index], index, array));
|
|
845
|
-
return set;
|
|
846
|
-
}
|
|
847
|
-
//#endregion
|
|
848
|
-
//#region src/internal/array/update.ts
|
|
849
|
-
function updateInArray(array, items, key, replace) {
|
|
850
|
-
if (!Array.isArray(array)) return [];
|
|
851
|
-
const itemsIsArray = Array.isArray(items);
|
|
852
|
-
if (array.length === 0 || !itemsIsArray) {
|
|
853
|
-
if (itemsIsArray) array.push(...items);
|
|
854
|
-
return array;
|
|
855
|
-
}
|
|
856
|
-
const { length } = items;
|
|
857
|
-
if (length === 0) return array;
|
|
858
|
-
const callback = getArrayCallback(key);
|
|
859
|
-
for (let valuesIndex = 0; valuesIndex < length; valuesIndex += 1) {
|
|
860
|
-
const item = items[valuesIndex];
|
|
861
|
-
const value = callback?.(item) ?? item;
|
|
862
|
-
const arrayIndex = callback == null ? array.indexOf(value) : array.findIndex((arrayItem, arrayIndex) => callback(arrayItem, arrayIndex, array) === value);
|
|
863
|
-
if (arrayIndex === -1) array.push(item);
|
|
864
|
-
else if (replace) array[arrayIndex] = item;
|
|
865
|
-
else array.splice(arrayIndex, 1);
|
|
866
|
-
}
|
|
867
|
-
return array;
|
|
868
|
-
}
|
|
869
|
-
//#endregion
|
|
870
|
-
//#region src/array/toggle.ts
|
|
871
|
-
function toggle(array, values, key) {
|
|
872
|
-
return updateInArray(array, values, key, false);
|
|
873
|
-
}
|
|
874
|
-
//#endregion
|
|
875
|
-
//#region src/array/union.ts
|
|
876
|
-
function union(first, second, key) {
|
|
877
|
-
return compareSets(COMPARE_SETS_UNION, first, second, key);
|
|
878
|
-
}
|
|
879
|
-
//#endregion
|
|
880
|
-
//#region src/array/unique.ts
|
|
881
|
-
function unique(array, key) {
|
|
882
|
-
if (!Array.isArray(array)) return [];
|
|
883
|
-
return array.length > 1 ? findValues(FIND_VALUES_UNIQUE, array, [key, void 0]).matched : array;
|
|
884
|
-
}
|
|
885
|
-
//#endregion
|
|
886
|
-
//#region src/array/update.ts
|
|
887
|
-
function update(array, values, key) {
|
|
888
|
-
return updateInArray(array, values, key, true);
|
|
889
|
-
}
|
|
890
|
-
//#endregion
|
|
891
|
-
//#region src/internal/array/overlap.ts
|
|
892
|
-
function arraysOverlap(first, second) {
|
|
893
|
-
const firstArray = first.index < second.index ? first.array : second.array;
|
|
894
|
-
const secondArray = first.index < second.index ? second.array : first.array;
|
|
895
|
-
const firstIndex = firstArray === first.array ? first.index : second.index;
|
|
896
|
-
const secondIndex = firstArray === first.array ? second.index : first.index;
|
|
897
|
-
const firstEnd = firstIndex + firstArray.length - 1;
|
|
898
|
-
return {
|
|
899
|
-
overlap: firstIndex <= secondIndex + secondArray.length - 1 && firstEnd >= secondIndex,
|
|
900
|
-
first: {
|
|
901
|
-
array: firstArray,
|
|
902
|
-
index: firstIndex
|
|
903
|
-
},
|
|
904
|
-
second: {
|
|
905
|
-
array: secondArray,
|
|
906
|
-
index: secondIndex
|
|
907
|
-
}
|
|
908
|
-
};
|
|
909
|
-
}
|
|
910
|
-
//#endregion
|
|
911
|
-
//#region src/array/move.ts
|
|
912
|
-
function move(array, from, to, key) {
|
|
913
|
-
if (!Array.isArray(array)) return [];
|
|
914
|
-
const firstArray = Array.isArray(from) ? from : [from];
|
|
915
|
-
const secondArray = Array.isArray(to) ? to : [to];
|
|
916
|
-
if (firstArray.length === 0 || secondArray.length === 0) return array;
|
|
917
|
-
const firstPosition = indexOfArray(array, firstArray, key);
|
|
918
|
-
const secondPosition = indexOfArray(array, secondArray, key);
|
|
919
|
-
if (firstPosition === -1 || secondPosition === -1 || firstPosition === secondPosition) return array;
|
|
920
|
-
const { overlap } = arraysOverlap({
|
|
921
|
-
array: firstArray,
|
|
922
|
-
index: firstPosition
|
|
923
|
-
}, {
|
|
924
|
-
array: secondArray,
|
|
925
|
-
index: secondPosition
|
|
926
|
-
});
|
|
927
|
-
if (overlap) return array;
|
|
928
|
-
array.splice(firstPosition, firstArray.length);
|
|
929
|
-
const next = secondPosition < firstPosition ? secondPosition : secondPosition + secondArray.length - firstArray.length;
|
|
930
|
-
if (next >= array.length) array.push(...firstArray);
|
|
931
|
-
else array.splice(next, 0, ...firstArray);
|
|
932
|
-
return array;
|
|
933
|
-
}
|
|
934
|
-
move.indices = moveIndices;
|
|
935
|
-
move.toIndex = moveToIndex;
|
|
936
|
-
/**
|
|
937
|
-
* Move an item from one index to another within an array
|
|
938
|
-
*
|
|
939
|
-
* If the from index is out of bounds, the array will be returned unchanged
|
|
940
|
-
* @param array Array to move within
|
|
941
|
-
* @param from Index to move from
|
|
942
|
-
* @param to Index to move to
|
|
943
|
-
* @returns Original array with item moved _(or unchanged if unable to move)_
|
|
944
|
-
*/
|
|
945
|
-
function moveIndices(array, from, to) {
|
|
946
|
-
if (!Array.isArray(array)) return [];
|
|
947
|
-
const { length } = array;
|
|
948
|
-
if (length === 0 || typeof from !== "number" || typeof to !== "number") return array;
|
|
949
|
-
const fromIndex = from < 0 ? length + from : from;
|
|
950
|
-
const toIndex = to < 0 ? length + to : to;
|
|
951
|
-
if (fromIndex === toIndex || fromIndex >= length || toIndex >= length) return array;
|
|
952
|
-
const spliced = array.splice(fromIndex, 1);
|
|
953
|
-
if (toIndex >= array.length) array.push(...spliced);
|
|
954
|
-
else array.splice(toIndex, 0, ...spliced);
|
|
955
|
-
return array;
|
|
956
|
-
}
|
|
957
|
-
function moveToIndex(array, value, index, key) {
|
|
958
|
-
if (!Array.isArray(array)) return [];
|
|
959
|
-
const { length } = array;
|
|
960
|
-
if (length === 0 || typeof index !== "number") return array;
|
|
961
|
-
const next = index < 0 ? length + index : index;
|
|
962
|
-
if (next >= length) return array;
|
|
963
|
-
const values = Array.isArray(value) ? value : [value];
|
|
964
|
-
const position = indexOfArray(array, values, key);
|
|
965
|
-
if (position === -1 || position === next) return array;
|
|
966
|
-
array.splice(position, values.length);
|
|
967
|
-
if (next >= array.length) array.push(...values);
|
|
968
|
-
else array.splice(next, 0, ...values);
|
|
969
|
-
return array;
|
|
970
|
-
}
|
|
971
|
-
//#endregion
|
|
972
985
|
//#region src/array/swap.ts
|
|
973
986
|
function swap(array, first, second, third) {
|
|
974
987
|
if (!Array.isArray(array)) return [];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oscarpalmer/atoms",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.168.0",
|
|
4
4
|
"description": "Atomic utilities for making your JavaScript better.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"helper",
|
|
@@ -44,6 +44,10 @@
|
|
|
44
44
|
"types": "./dist/array/move.d.mts",
|
|
45
45
|
"default": "./dist/array/move.mjs"
|
|
46
46
|
},
|
|
47
|
+
"./array/sort": {
|
|
48
|
+
"types": "./dist/array/sort.d.mts",
|
|
49
|
+
"default": "./dist/array/sort.mjs"
|
|
50
|
+
},
|
|
47
51
|
"./array/swap": {
|
|
48
52
|
"types": "./dist/array/swap.d.mts",
|
|
49
53
|
"default": "./dist/array/swap.mjs"
|
package/src/array/index.ts
CHANGED
package/src/array/sort.ts
CHANGED
|
@@ -43,6 +43,18 @@ type ArrayKeySorters<Item extends PlainObject> = {
|
|
|
43
43
|
[ItemKey in keyof Item]: ArrayKeySorter<Item, ItemKey>;
|
|
44
44
|
}[keyof Item];
|
|
45
45
|
|
|
46
|
+
/**
|
|
47
|
+
* Sorter to use for sorting
|
|
48
|
+
*/
|
|
49
|
+
type ArraySorter<Item> = Item extends PlainObject
|
|
50
|
+
?
|
|
51
|
+
| keyof Item
|
|
52
|
+
| ArrayComparisonSorter<Item>
|
|
53
|
+
| ArrayKeySorters<Item>
|
|
54
|
+
| ArrayValueSorter<Item>
|
|
55
|
+
| ComparisonSorter<Item>
|
|
56
|
+
: ArrayComparisonSorter<Item> | ArrayValueSorter<Item> | ComparisonSorter<Item>;
|
|
57
|
+
|
|
46
58
|
/**
|
|
47
59
|
* Sorting information for arrays _(using a value callback and built-in comparison)_
|
|
48
60
|
*/
|
|
@@ -74,41 +86,25 @@ type CompareCallbackValue<Item> = Item extends Primitive ? Item : unknown;
|
|
|
74
86
|
*/
|
|
75
87
|
type ComparisonSorter<Item> = (first: Item, second: Item) => number;
|
|
76
88
|
|
|
77
|
-
/**
|
|
78
|
-
* Internal sorter information
|
|
79
|
-
*/
|
|
80
89
|
type InternalSorter = {
|
|
81
|
-
compare?:
|
|
90
|
+
compare?: InternalSorterCompare;
|
|
82
91
|
get: boolean;
|
|
83
92
|
identifier: string;
|
|
84
93
|
modifier: number;
|
|
85
|
-
value?:
|
|
94
|
+
value?: Function;
|
|
86
95
|
};
|
|
87
96
|
|
|
88
|
-
|
|
89
|
-
* Direction to sort by
|
|
90
|
-
*/
|
|
91
|
-
export type SortDirection = 'ascending' | 'descending';
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
* Comparison callbacks for sorter
|
|
95
|
-
*/
|
|
96
|
-
type SorterCompare = {
|
|
97
|
+
type InternalSorterCompare = {
|
|
97
98
|
complex?: Function;
|
|
98
99
|
simple?: Function;
|
|
99
100
|
};
|
|
100
101
|
|
|
101
102
|
/**
|
|
102
|
-
*
|
|
103
|
+
* Direction to sort by
|
|
103
104
|
*/
|
|
104
|
-
type
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
| ArrayComparisonSorter<Item>
|
|
108
|
-
| ArrayKeySorters<Item>
|
|
109
|
-
| ArrayValueSorter<Item>
|
|
110
|
-
| ComparisonSorter<Item>
|
|
111
|
-
: ArrayComparisonSorter<Item> | ArrayValueSorter<Item> | ComparisonSorter<Item>;
|
|
105
|
+
export type SortDirection = 'ascending' | 'descending';
|
|
106
|
+
|
|
107
|
+
export type Sorter<Item> = (array: Item[]) => Item[];
|
|
112
108
|
|
|
113
109
|
// #endregion
|
|
114
110
|
|
|
@@ -125,6 +121,13 @@ function getComparisonSorter(callback: Function, modifier: number): InternalSort
|
|
|
125
121
|
};
|
|
126
122
|
}
|
|
127
123
|
|
|
124
|
+
function getModifier(first: unknown, second: unknown): number {
|
|
125
|
+
const direction =
|
|
126
|
+
first === true || second === true ? SORT_DIRECTION_DESCENDING : SORT_DIRECTION_ASCENDING;
|
|
127
|
+
|
|
128
|
+
return modifiers[direction];
|
|
129
|
+
}
|
|
130
|
+
|
|
128
131
|
function getObjectSorter(obj: PlainObject, modifier: number): InternalSorter | undefined {
|
|
129
132
|
let sorter: InternalSorter | undefined;
|
|
130
133
|
|
|
@@ -165,18 +168,70 @@ function getSorter(value: unknown, modifier: number): InternalSorter | undefined
|
|
|
165
168
|
}
|
|
166
169
|
}
|
|
167
170
|
|
|
171
|
+
function getSorters(value: unknown, modifier: number): InternalSorter[] {
|
|
172
|
+
const array = Array.isArray(value) ? value : [value];
|
|
173
|
+
const {length} = array;
|
|
174
|
+
|
|
175
|
+
const sorters: InternalSorter[] = [];
|
|
176
|
+
|
|
177
|
+
for (let index = 0; index < length; index += 1) {
|
|
178
|
+
const item = array[index];
|
|
179
|
+
|
|
180
|
+
const sorter = getSorter(item, modifier);
|
|
181
|
+
|
|
182
|
+
if (sorter != null) {
|
|
183
|
+
sorters.push(sorter);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
return sorters.filter(
|
|
188
|
+
(value, index, array) =>
|
|
189
|
+
array.findIndex(next => next.identifier === value.identifier) === index,
|
|
190
|
+
);
|
|
191
|
+
}
|
|
192
|
+
|
|
168
193
|
function getValueSorter(value: string | Function, modifier: number): InternalSorter {
|
|
169
194
|
return {
|
|
170
195
|
modifier,
|
|
171
196
|
get: true,
|
|
172
197
|
identifier: String(value),
|
|
173
|
-
value:
|
|
174
|
-
typeof value === 'function'
|
|
175
|
-
? (value as (item: PlainObject) => unknown)
|
|
176
|
-
: item => (item as PlainObject)[value],
|
|
198
|
+
value: typeof value === 'function' ? value : (item: unknown) => (item as PlainObject)[value],
|
|
177
199
|
};
|
|
178
200
|
}
|
|
179
201
|
|
|
202
|
+
/**
|
|
203
|
+
* Initialize a sort handler with sorters _(and an optional default direction)_
|
|
204
|
+
* @param sorters Sorters to use for sorting
|
|
205
|
+
* @param descending Sort in descending order? _(defaults to `false`; overridden by individual sorters)_
|
|
206
|
+
* @returns Sort handler
|
|
207
|
+
*/
|
|
208
|
+
function initializeSort<Item>(
|
|
209
|
+
sorters: Array<ArraySorter<Item>>,
|
|
210
|
+
descending?: boolean,
|
|
211
|
+
): Sorter<Item>;
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Initialize a sort handler with a sorter _(and an optional default direction)_
|
|
215
|
+
* @param sorter Sorter to use for sorting
|
|
216
|
+
* @param descending Sort in descending order? _(defaults to `false`; overridden by individual sorters)_
|
|
217
|
+
* @returns Sort handler
|
|
218
|
+
*/
|
|
219
|
+
function initializeSort<Item>(sorter: ArraySorter<Item>, descending?: boolean): Sorter<Item>;
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Initialize a sort handler _(with an optional default direction)_
|
|
223
|
+
* @param descending Sort in descending order? _(defaults to `false`)_
|
|
224
|
+
* @returns Sort handler
|
|
225
|
+
*/
|
|
226
|
+
function initializeSort<Item>(descending?: boolean): Sorter<Item>;
|
|
227
|
+
|
|
228
|
+
function initializeSort(first?: unknown, second?: unknown): Sorter<unknown> {
|
|
229
|
+
const modifier = getModifier(first, second);
|
|
230
|
+
const sorters = getSorters(first, modifier);
|
|
231
|
+
|
|
232
|
+
return array => work(array, sorters, modifier);
|
|
233
|
+
}
|
|
234
|
+
|
|
180
235
|
/**
|
|
181
236
|
* Sort an array of items, using multiple sorters to sort by specific values
|
|
182
237
|
* @param array Array to sort
|
|
@@ -186,7 +241,7 @@ function getValueSorter(value: string | Function, modifier: number): InternalSor
|
|
|
186
241
|
*/
|
|
187
242
|
export function sort<Item>(
|
|
188
243
|
array: Item[],
|
|
189
|
-
sorters: Array<
|
|
244
|
+
sorters: Array<ArraySorter<Item>>,
|
|
190
245
|
descending?: boolean,
|
|
191
246
|
): Item[];
|
|
192
247
|
|
|
@@ -197,7 +252,7 @@ export function sort<Item>(
|
|
|
197
252
|
* @param descending Sort in descending order? _(defaults to `false`; overridden by individual sorters)_
|
|
198
253
|
* @returns Sorted array
|
|
199
254
|
*/
|
|
200
|
-
export function sort<Item>(array: Item[], sorter:
|
|
255
|
+
export function sort<Item>(array: Item[], sorter: ArraySorter<Item>, descending?: boolean): Item[];
|
|
201
256
|
|
|
202
257
|
/**
|
|
203
258
|
* Sort an array of items
|
|
@@ -208,6 +263,12 @@ export function sort<Item>(array: Item[], sorter: Sorter<Item>, descending?: boo
|
|
|
208
263
|
export function sort<Item>(array: Item[], descending?: boolean): Item[];
|
|
209
264
|
|
|
210
265
|
export function sort(array: unknown[], first?: unknown, second?: unknown): unknown[] {
|
|
266
|
+
const modifier = getModifier(first, second);
|
|
267
|
+
|
|
268
|
+
return work(array, getSorters(first, modifier), modifier);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
function work(array: unknown[], sorters: InternalSorter[], modifier: number): unknown[] {
|
|
211
272
|
if (!Array.isArray(array)) {
|
|
212
273
|
return [];
|
|
213
274
|
}
|
|
@@ -216,51 +277,25 @@ export function sort(array: unknown[], first?: unknown, second?: unknown): unkno
|
|
|
216
277
|
return array;
|
|
217
278
|
}
|
|
218
279
|
|
|
219
|
-
const direction =
|
|
220
|
-
first === true || second === true ? SORT_DIRECTION_DESCENDING : SORT_DIRECTION_ASCENDING;
|
|
221
|
-
|
|
222
|
-
const modifier = modifiers[direction];
|
|
223
|
-
|
|
224
|
-
const sorters = (Array.isArray(first) ? first : [first])
|
|
225
|
-
.map(item => getSorter(item, modifier))
|
|
226
|
-
.filter(sorter => sorter != null)
|
|
227
|
-
.filter(
|
|
228
|
-
(current, index, filtered) =>
|
|
229
|
-
filtered.findIndex(next => next.identifier === current.identifier) === index,
|
|
230
|
-
);
|
|
231
|
-
|
|
232
280
|
const {length} = sorters;
|
|
233
281
|
|
|
234
282
|
if (length === 0) {
|
|
235
283
|
return array.sort((first, second) => compare(first, second) * modifier);
|
|
236
284
|
}
|
|
237
285
|
|
|
238
|
-
|
|
239
|
-
const sorter = sorters[0];
|
|
240
|
-
|
|
241
|
-
return array.sort((firstItem, secondItem) => {
|
|
242
|
-
const firstValue = sorter.get ? sorter.value!(firstItem as PlainObject) : firstItem;
|
|
243
|
-
const secondValue = sorter.get ? sorter.value!(secondItem as PlainObject) : secondItem;
|
|
244
|
-
|
|
245
|
-
return (
|
|
246
|
-
(sorter.compare?.complex?.(firstItem, firstValue, secondItem, secondValue) ??
|
|
247
|
-
sorter.compare?.simple?.(firstItem, secondItem) ??
|
|
248
|
-
compare(firstValue, secondValue)) * sorter.modifier
|
|
249
|
-
);
|
|
250
|
-
});
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
return array.sort((firstItem, secondItem) => {
|
|
286
|
+
return array.sort((first, second) => {
|
|
254
287
|
for (let index = 0; index < length; index += 1) {
|
|
255
288
|
const sorter = sorters[index];
|
|
256
289
|
|
|
257
|
-
const
|
|
258
|
-
|
|
290
|
+
const values = [
|
|
291
|
+
sorter.get ? sorter.value!(first as PlainObject) : first,
|
|
292
|
+
sorter.get ? sorter.value!(second as PlainObject) : second,
|
|
293
|
+
];
|
|
259
294
|
|
|
260
295
|
const comparison =
|
|
261
|
-
(sorter.compare?.complex?.(
|
|
262
|
-
sorter.compare?.simple?.(
|
|
263
|
-
compare(
|
|
296
|
+
(sorter.compare?.complex?.(first, values[0], second, values[1]) ??
|
|
297
|
+
sorter.compare?.simple?.(values[0], values[1]) ??
|
|
298
|
+
compare(values[0], values[1])) * sorter.modifier;
|
|
264
299
|
|
|
265
300
|
if (comparison !== 0) {
|
|
266
301
|
return comparison;
|
|
@@ -271,6 +306,8 @@ export function sort(array: unknown[], first?: unknown, second?: unknown): unkno
|
|
|
271
306
|
});
|
|
272
307
|
}
|
|
273
308
|
|
|
309
|
+
sort.initialize = initializeSort;
|
|
310
|
+
|
|
274
311
|
// #endregion
|
|
275
312
|
|
|
276
313
|
// #region Variables
|
package/src/index.ts
CHANGED