@rimbu/base 1.1.0 → 2.0.1

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/src/arr.mts CHANGED
@@ -1,12 +1,18 @@
1
- import { Update, TraverseState, type ArrayNonEmpty } from '@rimbu/common';
1
+ import { TraverseState, Update, type ArrayNonEmpty } from '@rimbu/common';
2
2
 
3
- // Returns a copy of the array with the given value appended
4
- export function append<T>(array: readonly T[], value: T): ArrayNonEmpty<T> {
3
+ export function _appendNew<T>(array: readonly T[], value: T): ArrayNonEmpty<T> {
4
+ return array.toSpliced(array.length, 0, value) as ArrayNonEmpty<T>;
5
+ }
6
+
7
+ export function _appendOld<T>(array: readonly T[], value: T): ArrayNonEmpty<T> {
5
8
  const clone = array.slice();
6
9
  clone.push(value);
7
10
  return clone as ArrayNonEmpty<T>;
8
11
  }
9
12
 
13
+ // Returns a copy of the array with the given value appended
14
+ export const append = `toSpliced` in Array.prototype ? _appendNew : _appendOld;
15
+
10
16
  // Returns the concatenation of the two arrays, potentially reusing the input array if one of the arrays is empty
11
17
  export function concat<T>(
12
18
  first: readonly T[],
@@ -17,23 +23,41 @@ export function concat<T>(
17
23
  return first.concat(second);
18
24
  }
19
25
 
20
- // Returns an copy of the array between the start and end indices, with the elements in reversed order.
21
- export function reverse<T>(
26
+ export function _reverseNew<T>(
27
+ array: readonly T[],
28
+ start?: number,
29
+ end?: number
30
+ ): T[] {
31
+ const source =
32
+ undefined !== start || undefined !== end
33
+ ? array.slice(start ?? 0, (end ?? array.length - 1) + 1)
34
+ : array;
35
+
36
+ return source.toReversed();
37
+ }
38
+
39
+ export function _reverseOld<T>(
22
40
  array: readonly T[],
23
- start = 0,
24
- end = array.length - 1
41
+ start?: number,
42
+ end?: number
25
43
  ): T[] {
26
- const length = end - start + 1;
44
+ const _start = start ?? 0;
45
+ const _end = end ?? array.length - 1;
46
+ const length = _end - _start + 1;
27
47
  const res = [] as T[];
28
48
 
29
- let arrayIndex = start - 1;
49
+ let arrayIndex = _start - 1;
30
50
  let resIndex = length - 1;
31
51
 
32
- while (++arrayIndex <= end) res[resIndex--] = array[arrayIndex];
52
+ while (++arrayIndex <= _end) res[resIndex--] = array[arrayIndex];
33
53
 
34
54
  return res;
35
55
  }
36
56
 
57
+ // Returns an copy of the array between the start and end indices, with the elements in reversed order.
58
+ export const reverse =
59
+ 'toReversed' in Array.prototype ? _reverseNew : _reverseOld;
60
+
37
61
  // Performs given function on each element of the array, in reverse order if 'reversed' is true.
38
62
  export function forEach<T>(
39
63
  array: readonly T[],
@@ -67,6 +91,11 @@ export function map<T, R>(
67
91
  f: (value: T, index: number) => R,
68
92
  indexOffset = 0
69
93
  ): R[] {
94
+ if (indexOffset === 0) {
95
+ // without offset, can use standard array map
96
+ return array.map(f);
97
+ }
98
+
70
99
  const result: R[] = [];
71
100
 
72
101
  let index = indexOffset;
@@ -95,59 +124,136 @@ export function reverseMap<T, R>(
95
124
  return result;
96
125
  }
97
126
 
98
- // Returns a copy of the given array with the given value added at the start
99
- export function prepend<T>(array: readonly T[], value: T): ArrayNonEmpty<T> {
127
+ export function _prependNew<T>(
128
+ array: readonly T[],
129
+ value: T
130
+ ): ArrayNonEmpty<T> {
131
+ return array.toSpliced(0, 0, value) as ArrayNonEmpty<T>;
132
+ }
133
+
134
+ export function _prependOld<T>(
135
+ array: readonly T[],
136
+ value: T
137
+ ): ArrayNonEmpty<T> {
100
138
  const clone = array.slice();
101
139
  clone.unshift(value);
102
140
  return clone as ArrayNonEmpty<T>;
103
141
  }
104
142
 
105
- // Returns the last element of the array
106
- export function last<T>(arr: readonly T[]): T {
143
+ // Returns a copy of the given array with the given value added at the start
144
+ export const prepend =
145
+ `toSpliced` in Array.prototype ? _prependNew : _prependOld;
146
+
147
+ export function _lastNew<T>(arr: readonly T[]): T {
148
+ return arr.at(-1)!;
149
+ }
150
+
151
+ export function _lastOld<T>(arr: readonly T[]): T {
107
152
  return arr[arr.length - 1];
108
153
  }
109
154
 
110
- // Returns a copy of the array where the element at given index is replaced by the given updater.
111
- // If the new element is the same as the old element, the original array is returned
112
- export function update<T>(
155
+ // Returns the last element of the array
156
+ export const last = `at` in Array.prototype ? _lastNew : _lastOld;
157
+
158
+ export function _updateNew<T>(
159
+ arr: readonly T[],
160
+ index: number,
161
+ updater: Update<T>
162
+ ): readonly T[] {
163
+ if (index < 0 || index >= arr.length) {
164
+ return arr;
165
+ }
166
+ const curValue = arr[index];
167
+
168
+ const newValue = Update(curValue, updater);
169
+ if (Object.is(newValue, curValue)) {
170
+ return arr;
171
+ }
172
+
173
+ return arr.with(index, newValue);
174
+ }
175
+
176
+ export function _updateOld<T>(
113
177
  arr: readonly T[],
114
178
  index: number,
115
179
  updater: Update<T>
116
180
  ): readonly T[] {
117
- if (index < 0 || index >= arr.length) return arr;
181
+ if (index < 0 || index >= arr.length) {
182
+ return arr;
183
+ }
118
184
  const curValue = arr[index];
119
185
 
120
186
  const newValue = Update(curValue, updater);
121
- if (Object.is(newValue, curValue)) return arr;
187
+ if (Object.is(newValue, curValue)) {
188
+ return arr;
189
+ }
190
+
122
191
  const newArr = arr.slice();
123
192
  newArr[index] = newValue;
124
193
  return newArr;
125
194
  }
126
195
 
127
- // Returns a copy of the array where the element at given index is replaced by applying given function.
196
+ // Returns a copy of the array where the element at given index is replaced by the given updater.
128
197
  // If the new element is the same as the old element, the original array is returned
129
- export function mod<T>(
198
+ export const update = `with` in Array.prototype ? _updateNew : _updateOld;
199
+
200
+ export function _modNew<T>(
130
201
  arr: readonly T[],
131
202
  index: number,
132
203
  f: (value: T) => T
133
204
  ): readonly T[] {
134
- if (index < 0 || index >= arr.length) return arr;
205
+ if (index < 0 || index >= arr.length) {
206
+ return arr;
207
+ }
135
208
 
136
209
  const curValue = arr[index];
137
210
  const newValue = f(curValue);
138
- if (Object.is(newValue, curValue)) return arr;
211
+
212
+ if (Object.is(newValue, curValue)) {
213
+ return arr;
214
+ }
215
+
216
+ return arr.with(index, newValue);
217
+ }
218
+
219
+ export function _modOld<T>(
220
+ arr: readonly T[],
221
+ index: number,
222
+ f: (value: T) => T
223
+ ): readonly T[] {
224
+ if (index < 0 || index >= arr.length) {
225
+ return arr;
226
+ }
227
+
228
+ const curValue = arr[index];
229
+ const newValue = f(curValue);
230
+
231
+ if (Object.is(newValue, curValue)) {
232
+ return arr;
233
+ }
234
+
139
235
  const newArr = arr.slice();
140
236
  newArr[index] = newValue;
141
237
  return newArr;
142
238
  }
143
239
 
144
- // Returns a copy of the array where at given index the given value is inserted
145
- export function insert<T>(arr: readonly T[], index: number, value: T): T[] {
240
+ // Returns a copy of the array where the element at given index is replaced by applying given function.
241
+ // If the new element is the same as the old element, the original array is returned
242
+ export const mod = `with` in Array.prototype ? _modNew : _modOld;
243
+
244
+ export function _insertNew<T>(arr: readonly T[], index: number, value: T): T[] {
245
+ return arr.toSpliced(index, 0, value);
246
+ }
247
+
248
+ export function _insertOld<T>(arr: readonly T[], index: number, value: T): T[] {
146
249
  const clone = arr.slice();
147
250
  clone.splice(index, 0, value);
148
251
  return clone;
149
252
  }
150
253
 
254
+ // Returns a copy of the array where at given index the given value is inserted
255
+ export const insert = `toSpliced` in Array.prototype ? _insertNew : _insertOld;
256
+
151
257
  // Returns a copy of the array, without its first element
152
258
  export function tail<T>(arr: readonly T[]): T[] {
153
259
  return arr.slice(1);
@@ -158,8 +264,16 @@ export function init<T>(arr: readonly T[]): T[] {
158
264
  return arr.slice(0, arr.length - 1);
159
265
  }
160
266
 
161
- // Immutable version of the array .splice command, always returns a new array
162
- export function splice<T>(
267
+ export function _spliceNew<T>(
268
+ arr: readonly T[],
269
+ start: number,
270
+ deleteCount: number,
271
+ ...items: T[]
272
+ ): T[] {
273
+ return arr.toSpliced(start, deleteCount, ...items);
274
+ }
275
+
276
+ export function _spliceOld<T>(
163
277
  arr: readonly T[],
164
278
  start: number,
165
279
  deleteCount: number,
@@ -170,6 +284,9 @@ export function splice<T>(
170
284
  return clone;
171
285
  }
172
286
 
287
+ // Immutable version of the array .splice command, always returns a new array
288
+ export const splice = `toSpliced` in Array.prototype ? _spliceNew : _spliceOld;
289
+
173
290
  // Returns a copy of the array, where its 'sparse' property is kept (sparse = not all indices have a value)
174
291
  export function copySparse<T>(arr: readonly T[]): T[] {
175
292
  const clone: T[] = [];
@@ -1,17 +0,0 @@
1
- import { Update, TraverseState, type ArrayNonEmpty } from '@rimbu/common';
2
- export declare function append<T>(array: readonly T[], value: T): ArrayNonEmpty<T>;
3
- export declare function concat<T>(first: readonly T[], second: readonly T[]): readonly T[];
4
- export declare function reverse<T>(array: readonly T[], start?: number, end?: number): T[];
5
- export declare function forEach<T>(array: readonly T[], f: (value: T, index: number, halt: () => void) => void, state?: TraverseState, reversed?: boolean): void;
6
- export declare function map<T, R>(array: readonly T[], f: (value: T, index: number) => R, indexOffset?: number): R[];
7
- export declare function reverseMap<T, R>(array: readonly T[], f: (value: T, index: number) => R, indexOffset?: number): R[];
8
- export declare function prepend<T>(array: readonly T[], value: T): ArrayNonEmpty<T>;
9
- export declare function last<T>(arr: readonly T[]): T;
10
- export declare function update<T>(arr: readonly T[], index: number, updater: Update<T>): readonly T[];
11
- export declare function mod<T>(arr: readonly T[], index: number, f: (value: T) => T): readonly T[];
12
- export declare function insert<T>(arr: readonly T[], index: number, value: T): T[];
13
- export declare function tail<T>(arr: readonly T[]): T[];
14
- export declare function init<T>(arr: readonly T[]): T[];
15
- export declare function splice<T>(arr: readonly T[], start: number, deleteCount: number, ...items: T[]): T[];
16
- export declare function copySparse<T>(arr: readonly T[]): T[];
17
- export declare function mapSparse<T, T2>(arr: readonly T[], f: (value: T, index: number) => T2): T2[];
File without changes
File without changes
File without changes
File without changes