@byloth/core 1.2.0 → 1.3.0-rc.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.
@@ -1,7 +1,18 @@
1
- import DeferredPromise from "./deferred-promise.js";
2
1
  import Exception from "./exception.js";
3
- import JsonStorage from "./json-storage.js";
4
2
  import SmartIterator from "./smart-iterator.js";
3
+ import Aggregator, { AggregatedIterator, ReducedIterator } from "./aggregators/index.js";
4
+
5
+ import DeferredPromise from "./deferred-promise.js";
6
+ import JsonStorage from "./json-storage.js";
5
7
  import Subscribers from "./subscribers.js";
6
8
 
7
- export { DeferredPromise, Exception, JsonStorage, SmartIterator, Subscribers };
9
+ export {
10
+ AggregatedIterator,
11
+ Aggregator,
12
+ DeferredPromise,
13
+ Exception,
14
+ JsonStorage,
15
+ ReducedIterator,
16
+ SmartIterator,
17
+ Subscribers
18
+ };
@@ -10,6 +10,7 @@ export default class SmartIterator<T, R = void, N = undefined> implements Iterat
10
10
  public constructor(iterable: Iterable<T>);
11
11
  public constructor(iterator: Iterator<T, R, N>);
12
12
  public constructor(generatorFn: GeneratorFunction<T, R, N>);
13
+ public constructor(argument: Iterable<T> | Iterator<T, R, N> | GeneratorFunction<T, R, N>);
13
14
  public constructor(argument: Iterable<T> | Iterator<T, R, N> | GeneratorFunction<T, R, N>)
14
15
  {
15
16
  if (argument instanceof Function)
@@ -60,13 +61,14 @@ export default class SmartIterator<T, R = void, N = undefined> implements Iterat
60
61
  }
61
62
  }
62
63
 
63
- public filter(predicate: Iteratee<T, boolean>): SmartIterator<T, R, N>
64
+ public filter(predicate: Iteratee<T, boolean>): SmartIterator<T, R>
64
65
  {
65
- let index = 0;
66
66
  const iterator = this._iterator;
67
67
 
68
- return new SmartIterator<T, R, N>(function* ()
68
+ return new SmartIterator<T, R>(function* ()
69
69
  {
70
+ let index = 0;
71
+
70
72
  while (true)
71
73
  {
72
74
  const result = iterator.next();
@@ -80,11 +82,12 @@ export default class SmartIterator<T, R = void, N = undefined> implements Iterat
80
82
  }
81
83
  public map<V>(iteratee: Iteratee<T, V>): SmartIterator<V, R>
82
84
  {
83
- let index = 0;
84
85
  const iterator = this._iterator;
85
86
 
86
87
  return new SmartIterator<V, R>(function* ()
87
88
  {
89
+ let index = 0;
90
+
88
91
  while (true)
89
92
  {
90
93
  const result = iterator.next();
@@ -96,10 +99,18 @@ export default class SmartIterator<T, R = void, N = undefined> implements Iterat
96
99
  }
97
100
  });
98
101
  }
99
- public reduce<A>(reducer: Reducer<T, A>, initialValue: A): A
102
+ public reduce<A>(reducer: Reducer<T, A>, initialValue?: A): A
100
103
  {
101
104
  let index = 0;
102
105
  let accumulator = initialValue;
106
+ if (accumulator === undefined)
107
+ {
108
+ const result = this._iterator.next();
109
+ if (result.done) { throw new TypeError("Reduce of empty iterator with no initial value"); }
110
+
111
+ accumulator = (result.value as unknown) as A;
112
+ index += 1;
113
+ }
103
114
 
104
115
  // eslint-disable-next-line no-constant-condition
105
116
  while (true)
@@ -113,6 +124,45 @@ export default class SmartIterator<T, R = void, N = undefined> implements Iterat
113
124
  }
114
125
  }
115
126
 
127
+ public enumerate(): SmartIterator<[number, T], R>
128
+ {
129
+ return this.map((value, index) => [index, value]);
130
+ }
131
+ public unique(): SmartIterator<T, R>
132
+ {
133
+ const iterator = this._iterator;
134
+
135
+ return new SmartIterator<T, R>(function* ()
136
+ {
137
+ const values = new Set<T>();
138
+
139
+ while (true)
140
+ {
141
+ const result = iterator.next();
142
+
143
+ if (result.done) { return result.value; }
144
+ if (values.has(result.value)) { continue; }
145
+
146
+ values.add(result.value);
147
+
148
+ yield result.value;
149
+ }
150
+ });
151
+ }
152
+
153
+ public count(): number
154
+ {
155
+ let index = 0;
156
+
157
+ // eslint-disable-next-line no-constant-condition
158
+ while (true)
159
+ {
160
+ const result = this._iterator.next();
161
+ if (result.done) { return index; }
162
+
163
+ index += 1;
164
+ }
165
+ }
116
166
  public forEach(iteratee: Iteratee<T>): void
117
167
  {
118
168
  let index = 0;
@@ -136,7 +186,7 @@ export default class SmartIterator<T, R = void, N = undefined> implements Iterat
136
186
 
137
187
  public toArray(): T[]
138
188
  {
139
- return [...this];
189
+ return Array.from(this as Iterable<T>);
140
190
  }
141
191
 
142
192
  public [Symbol.iterator](): SmartIterator<T, R, N> { return this; }
@@ -1,6 +1,10 @@
1
+ import Random from "./random.js";
2
+
1
3
  export { delay, nextAnimationFrame } from "./async.js";
2
4
  export { dateDifference, dateRange, dateRound, DateUnit } from "./date.js";
3
5
  export { loadScript } from "./dom.js";
4
6
  export { count, range, shuffle, unique, zip } from "./iterator.js";
5
- export { average, hash, random, sum } from "./math.js";
7
+ export { average, hash, sum } from "./math.js";
6
8
  export { capitalize } from "./string.js";
9
+
10
+ export { Random };
@@ -10,6 +10,21 @@ export function count<T>(elements: Iterable<T>): number
10
10
  return _count;
11
11
  }
12
12
 
13
+ export function enumerate<T>(elements: Iterable<T>): SmartIterator<[number, T]>
14
+ {
15
+ return new SmartIterator<[number, T]>(function* ()
16
+ {
17
+ let index = 0;
18
+
19
+ for (const element of elements)
20
+ {
21
+ yield [index, element];
22
+
23
+ index += 1;
24
+ }
25
+ });
26
+ }
27
+
13
28
  export function range(end: number): SmartIterator<number>;
14
29
  export function range(start: number, end: number): SmartIterator<number>;
15
30
  export function range(start: number, end: number, step: number): SmartIterator<number>;
@@ -31,7 +46,7 @@ export function range(start: number, end?: number, step = 1): SmartIterator<numb
31
46
 
32
47
  export function shuffle<T>(iterable: Iterable<T>): T[]
33
48
  {
34
- const array = [...iterable];
49
+ const array = Array.from(iterable);
35
50
 
36
51
  for (let index = array.length - 1; index > 0; index -= 1)
37
52
  {
@@ -47,13 +62,13 @@ export function unique<T>(elements: Iterable<T>): SmartIterator<T>
47
62
  {
48
63
  return new SmartIterator<T>(function* ()
49
64
  {
50
- const seen = new Set<T>();
65
+ const values = new Set<T>();
51
66
 
52
67
  for (const element of elements)
53
68
  {
54
- if (seen.has(element)) { continue; }
69
+ if (values.has(element)) { continue; }
55
70
 
56
- seen.add(element);
71
+ values.add(element);
57
72
 
58
73
  yield element;
59
74
  }
package/src/utils/math.ts CHANGED
@@ -33,9 +33,10 @@ export function average<T extends number>(values: Iterable<T>, weights?: Iterabl
33
33
  export function hash(value: string): number
34
34
  {
35
35
  let hashedValue = 0;
36
- for (let i = 0; i < value.length; i++)
36
+ for (let index = 0; index < value.length; index += 1)
37
37
  {
38
- const char = value.charCodeAt(i);
38
+ const char = value.charCodeAt(index);
39
+
39
40
  hashedValue = ((hashedValue << 5) - hashedValue) + char;
40
41
  hashedValue |= 0;
41
42
  }
@@ -43,55 +44,6 @@ export function hash(value: string): number
43
44
  return hashedValue;
44
45
  }
45
46
 
46
- export function random(): number;
47
- export function random(max: number): number;
48
- export function random(min: number, max: number): number;
49
- export function random(min: number, max: number, isDecimal: boolean): number;
50
- export function random(min: number, max: number, digits: number): number;
51
- export function random(min: number = 1, max?: number, decimals?: boolean | number): number
52
- {
53
- if (max === undefined)
54
- {
55
- max = min;
56
- min = 0;
57
- }
58
-
59
- if (min === max)
60
- {
61
- return min;
62
- }
63
-
64
- let rounder: (value: number) => number;
65
-
66
- if (decimals === true)
67
- {
68
- rounder = (value) => value;
69
- }
70
- else if (decimals === undefined)
71
- {
72
- if (Math.abs(max - min) <= 1)
73
- {
74
- rounder = (value) => value;
75
- }
76
- else
77
- {
78
- rounder = Math.floor;
79
- }
80
- }
81
- else if (decimals === false)
82
- {
83
- rounder = Math.floor;
84
- }
85
- else
86
- {
87
- const digits = 10 ** decimals;
88
-
89
- rounder = (value) => Math.floor(value * digits) / digits;
90
- }
91
-
92
- return rounder(Math.random() * (max - min) + min);
93
- }
94
-
95
47
  export function sum<T extends number>(values: Iterable<T>): number
96
48
  {
97
49
  let _sum = 0;
@@ -0,0 +1,39 @@
1
+ export default class Random
2
+ {
3
+ public static Boolean(ratio: number = 0.5): boolean
4
+ {
5
+ return (Math.random() < ratio);
6
+ }
7
+
8
+ public static Integer(max: number): number;
9
+ public static Integer(min: number, max: number): number;
10
+ public static Integer(min: number, max?: number): number
11
+ {
12
+ if (max === undefined)
13
+ {
14
+ return Math.floor(Math.random() * min);
15
+ }
16
+
17
+ return Math.floor(Math.random() * (max - min) + min);
18
+ }
19
+
20
+ public static Decimal(max: number): number;
21
+ public static Decimal(min: number, max: number): number;
22
+ public static Decimal(min: number, max?: number): number
23
+ {
24
+ if (max === undefined)
25
+ {
26
+ return (Math.random() * min);
27
+ }
28
+
29
+ return (Math.random() * (max - min) + min);
30
+ }
31
+
32
+ public static Choice<T>(elements: T[]): T
33
+ {
34
+ return elements[this.Integer(elements.length)];
35
+ }
36
+
37
+ // eslint-disable-next-line no-useless-constructor
38
+ private constructor() { }
39
+ }