Skip to content

Commit 7dcd5e7

Browse files
committed
feat: add reduce and reduceRight.
1 parent ad67754 commit 7dcd5e7

File tree

2 files changed

+226
-0
lines changed

2 files changed

+226
-0
lines changed

src/dynamicBuffer.ts

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -745,6 +745,132 @@ export class DynamicBuffer {
745745
return this.buffer[offset];
746746
}
747747

748+
/**
749+
* Calls the specified callback function for all the bytes in an buffer. The return value of
750+
* the callback function is the accumulated result, and is provided as an argument in the next
751+
* call to the callback function.
752+
*
753+
* @param callbackfn A function that accepts up to four arguments. The reduce method calls the
754+
* callbackfn function one time for each byte in the buffer.
755+
* @param initialValue If initialValue is specified, it is used as the initial value to start
756+
* the accumulation. The first call to the callbackfn function provides this value as an argument
757+
* instead of a byte value.
758+
*/
759+
reduce(
760+
callbackfn: (
761+
previousValue: number,
762+
currentValue: number,
763+
currentIndex: number,
764+
array: Uint8Array,
765+
) => number,
766+
): number;
767+
768+
reduce(
769+
callbackfn: (
770+
previousValue: number,
771+
currentValue: number,
772+
currentIndex: number,
773+
array: Uint8Array,
774+
) => number,
775+
initialValue: number,
776+
): number;
777+
778+
reduce<T>(
779+
callbackfn: (
780+
previousValue: T,
781+
currentValue: number,
782+
currentIndex: number,
783+
array: Uint8Array,
784+
) => T,
785+
initialValue: T,
786+
): T;
787+
788+
reduce(
789+
callbackfn: (
790+
previousValue: any,
791+
currentValue: number,
792+
currentIndex: number,
793+
array: Uint8Array,
794+
) => any,
795+
initialValue?: any,
796+
): any {
797+
if (!this.buffer || this.length <= 0) {
798+
if (initialValue === undefined) {
799+
throw new TypeError('Reduce of empty buffer with no initial value');
800+
}
801+
802+
return initialValue;
803+
}
804+
805+
if (initialValue !== undefined) {
806+
return this.buffer.subarray(0, this.length).reduce(callbackfn, initialValue);
807+
}
808+
return this.buffer.subarray(0, this.length).reduce(callbackfn);
809+
}
810+
811+
/**
812+
* Calls the specified callback function for all the bytes in the buffer, in descending order.
813+
* The return value of the callback function is the accumulated result, and is provided as an
814+
* argument in the next call to the callback function.
815+
*
816+
* @param callbackfn A function that accepts up to four arguments. The reduceRight method calls
817+
* the callbackfn function one time for each byte in the buffer.
818+
* @param initialValue If initialValue is specified, it is used as the initial value to start
819+
* the accumulation. The first call to the callbackfn function provides this value as an
820+
* argument instead of a byte value.
821+
*/
822+
reduceRight(
823+
callbackfn: (
824+
previousValue: number,
825+
currentValue: number,
826+
currentIndex: number,
827+
array: Uint8Array,
828+
) => number,
829+
): number;
830+
831+
reduceRight(
832+
callbackfn: (
833+
previousValue: number,
834+
currentValue: number,
835+
currentIndex: number,
836+
array: Uint8Array,
837+
) => number,
838+
initialValue: number,
839+
): number;
840+
841+
reduceRight<T>(
842+
callbackfn: (
843+
previousValue: T,
844+
currentValue: number,
845+
currentIndex: number,
846+
array: Uint8Array,
847+
) => T,
848+
initialValue: T,
849+
): T;
850+
851+
reduceRight(
852+
callbackfn: (
853+
previousValue: any,
854+
currentValue: number,
855+
currentIndex: number,
856+
array: Uint8Array,
857+
) => any,
858+
initialValue?: any,
859+
): any {
860+
if (!this.buffer || this.length <= 0) {
861+
if (initialValue === undefined) {
862+
throw new TypeError('ReduceRight of empty buffer with no initial value');
863+
}
864+
865+
return initialValue;
866+
}
867+
868+
if (initialValue !== undefined) {
869+
return this.buffer.subarray(0, this.length).reduceRight(callbackfn, initialValue);
870+
}
871+
return this.buffer.subarray(0, this.length).reduceRight(callbackfn);
872+
}
873+
748874
/**
749875
* Reverses the buffer in place and returns the reference to the buffer. The first byte in the
750876
* buffer now becoming the last, and the last byte in the buffer becoming the first.

test/array.spec.ts

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,106 @@ describe('Map tests', () => {
122122
});
123123
});
124124

125+
describe('Reduce tests', () => {
126+
it('Reduce buffer', () => {
127+
const buf = new DynamicBuffer('abc');
128+
129+
const ret = buf.reduce((prev, cur) => prev + (cur - 97));
130+
131+
assert.equal(ret, 100);
132+
});
133+
134+
it('Reduce buffer with initial value', () => {
135+
const buf = new DynamicBuffer('abc');
136+
137+
const ret = buf.reduce((prev, cur) => prev + (cur - 97), 0);
138+
139+
assert.equal(ret, 3);
140+
});
141+
142+
it('Reduce buffer with other type', () => {
143+
const buf = new DynamicBuffer('abc');
144+
145+
const ret = buf.reduce((prev, cur) => {
146+
const obj: any = { ...prev };
147+
obj[String.fromCharCode(cur)] = cur;
148+
return obj;
149+
}, {});
150+
151+
assert.deepEqual(ret, {
152+
a: 97,
153+
b: 98,
154+
c: 99,
155+
});
156+
});
157+
158+
it('Reduce empty buffer without initial value', () => {
159+
const buf = new DynamicBuffer();
160+
161+
assert.throws(() => {
162+
buf.reduce((prev, cur) => prev + (cur - 97));
163+
});
164+
});
165+
166+
it('Reduce empty buffer with initial value', () => {
167+
const buf = new DynamicBuffer();
168+
169+
const ret = buf.reduce((prev, cur) => prev + (cur - 97), 0);
170+
171+
assert.equal(ret, 0);
172+
});
173+
});
174+
175+
describe('ReduceRight tests', () => {
176+
it('ReduceRight buffer', () => {
177+
const buf = new DynamicBuffer('abc');
178+
179+
const ret = buf.reduceRight((prev, cur) => prev + (cur - 97));
180+
181+
assert.equal(ret, 100);
182+
});
183+
184+
it('ReduceRight buffer with initial value', () => {
185+
const buf = new DynamicBuffer('abc');
186+
187+
const ret = buf.reduceRight((prev, cur) => prev + (cur - 97), 0);
188+
189+
assert.equal(ret, 3);
190+
});
191+
192+
it('ReduceRight buffer with other type', () => {
193+
const buf = new DynamicBuffer('abc');
194+
195+
const ret = buf.reduceRight((prev, cur) => {
196+
const obj: any = { ...prev };
197+
obj[String.fromCharCode(cur)] = cur;
198+
return obj;
199+
}, {});
200+
201+
assert.deepEqual(ret, {
202+
a: 97,
203+
b: 98,
204+
c: 99,
205+
});
206+
});
207+
208+
it('ReduceRight empty buffer without initial value', () => {
209+
const buf = new DynamicBuffer();
210+
211+
assert.throws(() => {
212+
buf.reduceRight((prev, cur) => prev + (cur - 97));
213+
});
214+
});
215+
216+
it('ReduceRight empty buffer with initial value', () => {
217+
const buf = new DynamicBuffer();
218+
219+
const ret = buf.reduceRight((prev, cur) => prev + (cur - 97), 0);
220+
221+
assert.equal(ret, 0);
222+
});
223+
});
224+
125225
describe('Reverse tests', () => {
126226
it('Reverse buffer', () => {
127227
const buf = new DynamicBuffer('hello');

0 commit comments

Comments
 (0)