Implement TypedArray#reduce/reduceRight (#352)

This commit is contained in:
jtenner
2018-12-05 11:53:31 -05:00
committed by Daniel Wirtz
parent ced01216f8
commit d7f4874650
7 changed files with 5079 additions and 8 deletions

View File

@ -520,6 +520,16 @@ declare abstract class TypedArray<T> implements ArrayBufferView<T> {
readonly length: i32;
/** Returns a new TypedArray of this type on the same ArrayBuffer from begin inclusive to end exclusive. */
subarray(begin?: i32, end?: i32): this;
/** The reduce() method applies a function against an accumulator and each value of the typed array (from left-to-right) has to reduce it to a single value. This method has the same algorithm as Array.prototype.reduce(). */
reduce<W>(
callbackfn: (accumulator: W, value: T, index: i32, self: this) => W,
initialValue: W,
): W;
/** The reduceRight() method applies a function against an accumulator and each value of the typed array (from left-to-right) has to reduce it to a single value, starting from the end of the array. This method has the same algorithm as Array.prototype.reduceRight(). */
reduceRight<W>(
callbackfn: (accumulator: W, value: T, index: i32, self: this) => W,
initialValue: W,
): W;
}
/** An array of twos-complement 8-bit signed integers. */

View File

@ -126,4 +126,31 @@ export abstract class TypedArray<T,TNative> {
return this;
}
}
/**
* TypedArray reduce implementation. This is a method that will be called from the parent,
* passing types down from the child class using the typed parameters TypedArrayType and
* ReturnType respectively. This implementation requires an initial value, and the direction.
* When direction is true, reduce will reduce from the right side.
*/
@inline
protected reduce_internal<TypedArrayType, ReturnType>(
callbackfn: (accumulator: ReturnType, value: T, index: i32, array: TypedArrayType) => ReturnType,
array: TypedArrayType,
initialValue: ReturnType,
direction: bool = false,
): ReturnType {
var index: i32 = direction ? this.length - 1 : 0;
var length: i32 = direction ? -1 : this.length;
while (index != length) {
initialValue = callbackfn(
initialValue,
this.__unchecked_get(index),
index,
array,
);
index = direction ? index - 1 : index + 1;
}
return initialValue;
}
}

View File

@ -8,6 +8,20 @@ export class Int8Array extends TypedArray<i8,i32> {
subarray(begin: i32 = 0, end: i32 = 0x7fffffff): Int8Array {
return changetype<Int8Array>(super.subarray(begin, end));
}
reduce<ReturnType>(
callbackfn: (accumulator: ReturnType, value: i8, index: i32, array: Int8Array) => ReturnType,
initialValue: ReturnType,
): ReturnType {
return super.reduce_internal<Int8Array, ReturnType>(callbackfn, this, initialValue);
}
reduceRight<ReturnType>(
callbackfn: (accumulator: ReturnType, value: i8, index: i32, array: Int8Array) => ReturnType,
initialValue: ReturnType,
): ReturnType {
return super.reduce_internal<Int8Array, ReturnType>(callbackfn, this, initialValue, true);
}
}
export class Uint8Array extends TypedArray<u8,u32> {
@ -16,6 +30,20 @@ export class Uint8Array extends TypedArray<u8,u32> {
subarray(begin: i32 = 0, end: i32 = 0x7fffffff): Uint8Array {
return changetype<Uint8Array>(super.subarray(begin, end));
}
reduce<ReturnType>(
callbackfn: (accumulator: ReturnType, value: u8, index: i32, array: Uint8Array) => ReturnType,
initialValue: ReturnType,
): ReturnType {
return super.reduce_internal<Uint8Array, ReturnType>(callbackfn, this, initialValue);
}
reduceRight<ReturnType>(
callbackfn: (accumulator: ReturnType, value: u8, index: i32, array: Uint8Array) => ReturnType,
initialValue: ReturnType,
): ReturnType {
return super.reduce_internal<Uint8Array, ReturnType>(callbackfn, this, initialValue, true);
}
}
export class Uint8ClampedArray extends TypedArray<u8,u32> {
@ -34,6 +62,20 @@ export class Uint8ClampedArray extends TypedArray<u8,u32> {
subarray(begin: i32 = 0, end: i32 = 0x7fffffff): Uint8ClampedArray {
return changetype<Uint8ClampedArray>(super.subarray(begin, end));
}
reduce<ReturnType>(
callbackfn: (accumulator: ReturnType, value: u8, index: i32, array: Uint8ClampedArray) => ReturnType,
initialValue: ReturnType,
): ReturnType {
return super.reduce_internal<Uint8ClampedArray, ReturnType>(callbackfn, this, initialValue);
}
reduceRight<ReturnType>(
callbackfn: (accumulator: ReturnType, value: u8, index: i32, array: Uint8ClampedArray) => ReturnType,
initialValue: ReturnType,
): ReturnType {
return super.reduce_internal<Uint8ClampedArray, ReturnType>(callbackfn, this, initialValue, true);
}
}
export class Int16Array extends TypedArray<i16,i32> {
@ -42,6 +84,20 @@ export class Int16Array extends TypedArray<i16,i32> {
subarray(begin: i32 = 0, end: i32 = 0x7fffffff): Int16Array {
return changetype<Int16Array>(super.subarray(begin, end));
}
reduce<ReturnType>(
callbackfn: (accumulator: ReturnType, value: i16, index: i32, array: Int16Array) => ReturnType,
initialValue: ReturnType,
): ReturnType {
return super.reduce_internal<Int16Array, ReturnType>(callbackfn, this, initialValue);
}
reduceRight<ReturnType>(
callbackfn: (accumulator: ReturnType, value: i16, index: i32, array: Int16Array) => ReturnType,
initialValue: ReturnType,
): ReturnType {
return super.reduce_internal<Int16Array, ReturnType>(callbackfn, this, initialValue, true);
}
}
export class Uint16Array extends TypedArray<u16,u32> {
@ -50,6 +106,20 @@ export class Uint16Array extends TypedArray<u16,u32> {
subarray(begin: i32 = 0, end: i32 = 0x7fffffff): Uint16Array {
return changetype<Uint16Array>(super.subarray(begin, end));
}
reduce<ReturnType>(
callbackfn: (accumulator: ReturnType, value: u16, index: i32, array: Uint16Array) => ReturnType,
initialValue: ReturnType,
): ReturnType {
return super.reduce_internal<Uint16Array, ReturnType>(callbackfn, this, initialValue);
}
reduceRight<ReturnType>(
callbackfn: (accumulator: ReturnType, value: u16, index: i32, array: Uint16Array) => ReturnType,
initialValue: ReturnType,
): ReturnType {
return super.reduce_internal<Uint16Array, ReturnType>(callbackfn, this, initialValue, true);
}
}
export class Int32Array extends TypedArray<i32,i32> {
@ -58,6 +128,24 @@ export class Int32Array extends TypedArray<i32,i32> {
subarray(begin: i32 = 0, end: i32 = 0x7fffffff): Int32Array {
return changetype<Int32Array>(super.subarray(begin, end));
}
/**
* @param callbackfn {function} - a function that reduces each value to a ReturnType
* @param initialValue {ReturnType} - the initial ReturnType value to be passed to the callbackfn
*/
reduce<ReturnType>(
callbackfn: (accumulator: ReturnType, value: i32, index: i32, array: Int32Array) => ReturnType,
initialValue: ReturnType,
): ReturnType {
return super.reduce_internal<Int32Array, ReturnType>(callbackfn, this, initialValue);
}
reduceRight<ReturnType>(
callbackfn: (accumulator: ReturnType, value: i32, index: i32, array: Int32Array) => ReturnType,
initialValue: ReturnType,
): ReturnType {
return super.reduce_internal<Int32Array, ReturnType>(callbackfn, this, initialValue, true);
}
}
export class Uint32Array extends TypedArray<u32,u32> {
@ -66,6 +154,20 @@ export class Uint32Array extends TypedArray<u32,u32> {
subarray(begin: i32 = 0, end: i32 = 0x7fffffff): Uint32Array {
return changetype<Uint32Array>(super.subarray(begin, end));
}
reduce<ReturnType>(
callbackfn: (accumulator: ReturnType, value: u32, index: i32, array: Uint32Array) => ReturnType,
initialValue: ReturnType,
): ReturnType {
return super.reduce_internal<Uint32Array, ReturnType>(callbackfn, this, initialValue);
}
reduceRight<ReturnType>(
callbackfn: (accumulator: ReturnType, value: u32, index: i32, array: Uint32Array) => ReturnType,
initialValue: ReturnType,
): ReturnType {
return super.reduce_internal<Uint32Array, ReturnType>(callbackfn, this, initialValue, true);
}
}
export class Int64Array extends TypedArray<i64,i64> {
@ -74,6 +176,20 @@ export class Int64Array extends TypedArray<i64,i64> {
subarray(begin: i32 = 0, end: i32 = 0x7fffffff): Int64Array {
return changetype<Int64Array>(super.subarray(begin, end));
}
reduce<ReturnType>(
callbackfn: (accumulator: ReturnType, value: i64, index: i32, array: Int64Array) => ReturnType,
initialValue: ReturnType,
): ReturnType {
return super.reduce_internal<Int64Array, ReturnType>(callbackfn, this, initialValue);
}
reduceRight<ReturnType>(
callbackfn: (accumulator: ReturnType, value: i64, index: i32, array: Int64Array) => ReturnType,
initialValue: ReturnType,
): ReturnType {
return super.reduce_internal<Int64Array, ReturnType>(callbackfn, this, initialValue, true);
}
}
export class Uint64Array extends TypedArray<u64,u64> {
@ -82,6 +198,20 @@ export class Uint64Array extends TypedArray<u64,u64> {
subarray(begin: i32 = 0, end: i32 = 0x7fffffff): Uint64Array {
return changetype<Uint64Array>(super.subarray(begin, end));
}
reduce<ReturnType>(
callbackfn: (accumulator: ReturnType, value: u64, index: i32, array: Uint64Array) => ReturnType,
initialValue: ReturnType,
): ReturnType {
return super.reduce_internal<Uint64Array, ReturnType>(callbackfn, this, initialValue);
}
reduceRight<ReturnType>(
callbackfn: (accumulator: ReturnType, value: u64, index: i32, array: Uint64Array) => ReturnType,
initialValue: ReturnType,
): ReturnType {
return super.reduce_internal<Uint64Array, ReturnType>(callbackfn, this, initialValue, true);
}
}
export class Float32Array extends TypedArray<f32,f32> {
@ -90,6 +220,20 @@ export class Float32Array extends TypedArray<f32,f32> {
subarray(begin: i32 = 0, end: i32 = 0x7fffffff): Float32Array {
return changetype<Float32Array>(super.subarray(begin, end));
}
reduce<ReturnType>(
callbackfn: (accumulator: ReturnType, value: f32, index: i32, array: Float32Array) => ReturnType,
initialValue: ReturnType,
): ReturnType {
return super.reduce_internal<Float32Array, ReturnType>(callbackfn, this, initialValue);
}
reduceRight<ReturnType>(
callbackfn: (accumulator: ReturnType, value: f32, index: i32, array: Float32Array) => ReturnType,
initialValue: ReturnType,
): ReturnType {
return super.reduce_internal<Float32Array, ReturnType>(callbackfn, this, initialValue, true);
}
}
export class Float64Array extends TypedArray<f64,f64> {
@ -98,4 +242,18 @@ export class Float64Array extends TypedArray<f64,f64> {
subarray(begin: i32 = 0, end: i32 = 0x7fffffff): Float64Array {
return changetype<Float64Array>(super.subarray(begin, end));
}
reduce<ReturnType>(
callbackfn: (accumulator: ReturnType, value: f64, index: i32, array: Float64Array) => ReturnType,
initialValue: ReturnType,
): ReturnType {
return super.reduce_internal<Float64Array, ReturnType>(callbackfn, this, initialValue);
}
reduceRight<ReturnType>(
callbackfn: (accumulator: ReturnType, value: f64, index: i32, array: Float64Array) => ReturnType,
initialValue: ReturnType,
): ReturnType {
return super.reduce_internal<Float64Array, ReturnType>(callbackfn, this, initialValue, true);
}
}