mirror of
https://github.com/fluencelabs/assemblyscript
synced 2025-05-09 13:52:17 +00:00
Implement Array#map, Array#forEach, Array#filter, Array#reduceRight (#81)
This commit is contained in:
parent
05117f9ee3
commit
fac0fc59b5
std
tests/compiler/std
6
std/assembly.d.ts
vendored
6
std/assembly.d.ts
vendored
@ -337,14 +337,18 @@ declare class Array<T> {
|
|||||||
lastIndexOf(searchElement: T, fromIndex?: i32): i32;
|
lastIndexOf(searchElement: T, fromIndex?: i32): i32;
|
||||||
push(element: T): void;
|
push(element: T): void;
|
||||||
pop(): T;
|
pop(): T;
|
||||||
|
forEach(callbackfn: (value: T, index: i32, array: Array<T>) => void): void;
|
||||||
|
map<U>(callbackfn: (value: T, index: i32, array: Array<T>) => U): Array<U>;
|
||||||
|
filter(callbackfn: (value: T, index: i32, array: Array<T>) => bool): Array<T>;
|
||||||
reduce<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: i32, array: Array<T>) => U, initialValue: U): U;
|
reduce<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: i32, array: Array<T>) => U, initialValue: U): U;
|
||||||
|
reduceRight<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: i32, array: Array<T>) => U, initialValue: U): U;
|
||||||
shift(): T;
|
shift(): T;
|
||||||
some(callbackfn: (element: T, index: i32, array?: Array<T>) => bool): bool;
|
some(callbackfn: (element: T, index: i32, array?: Array<T>) => bool): bool;
|
||||||
unshift(element: T): i32;
|
unshift(element: T): i32;
|
||||||
slice(from: i32, to?: i32): T[];
|
slice(from: i32, to?: i32): T[];
|
||||||
splice(start: i32, deleteCount?: i32): void;
|
splice(start: i32, deleteCount?: i32): void;
|
||||||
reverse(): T[];
|
reverse(): T[];
|
||||||
sort(comparator?: (a: T, b: T) => i32): T[];
|
sort(comparator?: (a: T, b: T) => i32): this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Class representing a C-like array of values of type `T` with limited capabilities. */
|
/** Class representing a C-like array of values of type `T` with limited capabilities. */
|
||||||
|
@ -142,6 +142,35 @@ export class Array<T> {
|
|||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
forEach(callbackfn: (value: T, index: i32, array: Array<T>) => void): void {
|
||||||
|
var buffer = this.buffer_;
|
||||||
|
for (let index = 0, toIndex = this.length_; index < toIndex && index < this.length_; ++index) {
|
||||||
|
callbackfn(loadUnsafe<T>(buffer, index), index, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
map<U>(callbackfn: (value: T, index: i32, array: Array<T>) => U): Array<U> {
|
||||||
|
var buffer = this.buffer_;
|
||||||
|
var length = this.length_;
|
||||||
|
var result = new Array<U>(length);
|
||||||
|
var resultBuffer = result.buffer_;
|
||||||
|
for (let index = 0; index < length && index < this.length_; ++index) {
|
||||||
|
storeUnsafe<U>(resultBuffer, index, callbackfn(loadUnsafe<T>(buffer, index), index, this));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
filter(callbackfn: (value: T, index: i32, array: Array<T>) => bool): Array<T> {
|
||||||
|
var buffer = this.buffer_;
|
||||||
|
var length = this.length_;
|
||||||
|
var result = new Array<T>();
|
||||||
|
for (let index = 0; index < length && index < this.length_; ++index) {
|
||||||
|
let value = loadUnsafe<T>(buffer, index);
|
||||||
|
if (callbackfn(value, index, this)) result.push(value);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
reduce<U>(
|
reduce<U>(
|
||||||
callbackfn: (previousValue: U, currentValue: T, currentIndex: i32, array: Array<T>) => U,
|
callbackfn: (previousValue: U, currentValue: T, currentIndex: i32, array: Array<T>) => U,
|
||||||
initialValue: U
|
initialValue: U
|
||||||
@ -154,6 +183,18 @@ export class Array<T> {
|
|||||||
return accum;
|
return accum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
reduceRight<U>(
|
||||||
|
callbackfn: (previousValue: U, currentValue: T, currentIndex: i32, array: Array<T>) => U,
|
||||||
|
initialValue: U
|
||||||
|
): U {
|
||||||
|
var accum = initialValue;
|
||||||
|
var buffer = this.buffer_;
|
||||||
|
for (let index: i32 = this.length_ - 1; index >= 0; --index) {
|
||||||
|
accum = callbackfn(accum, loadUnsafe<T>(buffer, index), index, this);
|
||||||
|
}
|
||||||
|
return accum;
|
||||||
|
}
|
||||||
|
|
||||||
shift(): T {
|
shift(): T {
|
||||||
var length = this.length_;
|
var length = this.length_;
|
||||||
if (length < 1) throw new RangeError("Array is empty");
|
if (length < 1) throw new RangeError("Array is empty");
|
||||||
@ -245,7 +286,7 @@ export class Array<T> {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
sort(comparator: (a: T, b: T) => i32 = defaultComparator<T>()): Array<T> {
|
sort(comparator: (a: T, b: T) => i32 = defaultComparator<T>()): this {
|
||||||
var length = this.length_;
|
var length = this.length_;
|
||||||
if (length <= 1) return this;
|
if (length <= 1) return this;
|
||||||
var buffer = this.buffer_;
|
var buffer = this.buffer_;
|
||||||
|
6
std/portable.d.ts
vendored
6
std/portable.d.ts
vendored
@ -237,14 +237,18 @@ declare class Array<T> {
|
|||||||
lastIndexOf(searchElement: T, fromIndex?: i32): i32;
|
lastIndexOf(searchElement: T, fromIndex?: i32): i32;
|
||||||
push(element: T): void;
|
push(element: T): void;
|
||||||
pop(): T;
|
pop(): T;
|
||||||
|
forEach(callbackfn: (value: T, index: i32, array: Array<T>) => void): void;
|
||||||
|
map<U>(callbackfn: (value: T, index: i32, array: Array<T>) => U): Array<U>;
|
||||||
|
filter(callbackfn: (value: T, index: i32, array: Array<T>) => bool): Array<T>;
|
||||||
reduce<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: i32, array: Array<T>) => U, initialValue: U): U;
|
reduce<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: i32, array: Array<T>) => U, initialValue: U): U;
|
||||||
|
reduceRight<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: i32, array: Array<T>) => U, initialValue: U): U;
|
||||||
shift(): T;
|
shift(): T;
|
||||||
some(callbackfn: (element: T, index: i32, array?: Array<T>) => bool): bool;
|
some(callbackfn: (element: T, index: i32, array?: Array<T>) => bool): bool;
|
||||||
unshift(element: T): i32;
|
unshift(element: T): i32;
|
||||||
slice(from: i32, to?: i32): T[];
|
slice(from: i32, to?: i32): T[];
|
||||||
splice(start: i32, deleteCount?: i32): void;
|
splice(start: i32, deleteCount?: i32): void;
|
||||||
reverse(): T[];
|
reverse(): T[];
|
||||||
sort(comparator?: (a: T, b: T) => i32): T[];
|
sort(comparator?: (a: T, b: T) => i32): this;
|
||||||
|
|
||||||
join(delim: string): string;
|
join(delim: string): string;
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -312,6 +312,127 @@ assert(arr.length == 2);
|
|||||||
arr.push(2);
|
arr.push(2);
|
||||||
arr.push(3);
|
arr.push(3);
|
||||||
|
|
||||||
|
// Array#forEach ///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
arr.forEach((value: i32, index: i32, array: Array<i32>): void => { i += value; });
|
||||||
|
assert(i == 6);
|
||||||
|
|
||||||
|
// Test side effect push
|
||||||
|
i = 0;
|
||||||
|
arr.forEach((value: i32, index: i32, array: Array<i32>): void => {
|
||||||
|
array.push(100); //push side effect should not affect this method by spec
|
||||||
|
i += value;
|
||||||
|
});
|
||||||
|
// array should be changed, but this method result should be calculated for old array length
|
||||||
|
assert(i == 6);
|
||||||
|
assert(arr.length == 8);
|
||||||
|
i = 0;
|
||||||
|
arr.forEach((value: i32, index: i32, array: Array<i32>): void => { i += value; });
|
||||||
|
assert(i == 406);
|
||||||
|
|
||||||
|
arr.pop();
|
||||||
|
arr.pop();
|
||||||
|
arr.pop();
|
||||||
|
arr.pop();
|
||||||
|
|
||||||
|
// Test side effect pop
|
||||||
|
i = 0;
|
||||||
|
arr.forEach((value: i32, index: i32, array: Array<i32>): void => {
|
||||||
|
array.pop(); //poped items shouldn't be looked up, and we shouldn't go out of bounds
|
||||||
|
i += value;
|
||||||
|
});
|
||||||
|
// only 2 first items was looked up, since last 2 was removed by .pop()
|
||||||
|
assert(i == 1);
|
||||||
|
assert(arr.length == 2);
|
||||||
|
|
||||||
|
arr.push(2);
|
||||||
|
arr.push(3);
|
||||||
|
|
||||||
|
|
||||||
|
// Array#map ///////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
var newArr: f32[] = arr.map<f32>((value: i32, index: i32, array: Array<i32>): f32 => <f32>value);
|
||||||
|
assert(newArr.length == 4);
|
||||||
|
assert(newArr[0] == <f32>arr[0]);
|
||||||
|
|
||||||
|
// Test side effect push
|
||||||
|
i = 0;
|
||||||
|
arr.map<i32>((value: i32, index: i32, array: Array<i32>): i32 => {
|
||||||
|
array.push(100); //push side effect should not affect this method by spec
|
||||||
|
i += value;
|
||||||
|
return value;
|
||||||
|
});
|
||||||
|
assert(i == 6);
|
||||||
|
assert(arr.length == 8);
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
arr.map<i32>((value: i32, index: i32, array: Array<i32>): i32 => {
|
||||||
|
i += value;
|
||||||
|
return value;
|
||||||
|
});
|
||||||
|
assert(i == 406);
|
||||||
|
|
||||||
|
arr.pop();
|
||||||
|
arr.pop();
|
||||||
|
arr.pop();
|
||||||
|
arr.pop();
|
||||||
|
|
||||||
|
// Test side effect pop
|
||||||
|
i = 0;
|
||||||
|
arr.map<i32>((value: i32, index: i32, array: Array<i32>): i32 => {
|
||||||
|
array.pop(); //poped items shouldn't be looked up, and we shouldn't go out of bounds
|
||||||
|
i += value;
|
||||||
|
return value;
|
||||||
|
});
|
||||||
|
// only 2 first items was looked up, since last 2 was removed by .pop()
|
||||||
|
assert(i == 1);
|
||||||
|
assert(arr.length == 2);
|
||||||
|
|
||||||
|
arr.push(2);
|
||||||
|
arr.push(3);
|
||||||
|
|
||||||
|
// Array#filter ////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
var filteredArr: i32[] = arr.filter((value: i32, index: i32, array: Array<i32>): bool => value >= 2);
|
||||||
|
assert(filteredArr.length == 2);
|
||||||
|
|
||||||
|
// Test side effect push
|
||||||
|
i = 0;
|
||||||
|
arr.filter((value: i32, index: i32, array: Array<i32>): bool => {
|
||||||
|
array.push(100); //push side effect should not affect this method by spec
|
||||||
|
i += value;
|
||||||
|
return value >= 2;
|
||||||
|
});
|
||||||
|
assert(i == 6);
|
||||||
|
assert(arr.length == 8);
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
arr.filter((value: i32, index: i32, array: Array<i32>): bool => {
|
||||||
|
i += value;
|
||||||
|
return value >= 2;
|
||||||
|
});
|
||||||
|
assert(i == 406);
|
||||||
|
|
||||||
|
arr.pop();
|
||||||
|
arr.pop();
|
||||||
|
arr.pop();
|
||||||
|
arr.pop();
|
||||||
|
|
||||||
|
// Test side effect pop
|
||||||
|
i = 0;
|
||||||
|
arr.filter((value: i32, index: i32, array: Array<i32>): bool => {
|
||||||
|
array.pop(); //poped items shouldn't be looked up, and we shouldn't go out of bounds
|
||||||
|
i += value;
|
||||||
|
return value >= 2;
|
||||||
|
});
|
||||||
|
// only 2 first items was looked up, since last 2 was removed by .pop()
|
||||||
|
assert(i == 1);
|
||||||
|
assert(arr.length == 2);
|
||||||
|
|
||||||
|
arr.push(2);
|
||||||
|
arr.push(3);
|
||||||
|
|
||||||
// Array#reduce ////////////////////////////////////////////////////////////////////////////////////
|
// Array#reduce ////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
i = arr.reduce<i32>(((prev: i32, current: i32, index: i32, array: Array<i32>): i32 => prev + current), 0);
|
i = arr.reduce<i32>(((prev: i32, current: i32, index: i32, array: Array<i32>): i32 => prev + current), 0);
|
||||||
@ -352,6 +473,54 @@ i = arr.reduce<i32>(((prev: i32, current: i32, index: i32, array: Array<i32>): i
|
|||||||
assert(i == 1);
|
assert(i == 1);
|
||||||
assert(arr.length == 2);
|
assert(arr.length == 2);
|
||||||
|
|
||||||
|
arr.push(2);
|
||||||
|
arr.push(3);
|
||||||
|
|
||||||
|
// Array#reduceRight ///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
i = arr.reduceRight<i32>(((prev: i32, current: i32, index: i32, array: Array<i32>): i32 => prev + current), 0);
|
||||||
|
assert(i == 6);
|
||||||
|
|
||||||
|
// init value
|
||||||
|
i = arr.reduceRight<i32>(((prev: i32, current: i32, index: i32, array: Array<i32>): i32 => prev + current), 4);
|
||||||
|
assert(i == 10);
|
||||||
|
|
||||||
|
boolVal = arr.reduceRight<bool>(((prev: bool, current: i32, index: i32, array: Array<i32>): bool => prev || current > 2), false);
|
||||||
|
assert(boolVal == true);
|
||||||
|
|
||||||
|
boolVal = arr.reduceRight<bool>(((prev: bool, current: i32, index: i32, array: Array<i32>): bool => prev || current > 100), false);
|
||||||
|
assert(boolVal == false);
|
||||||
|
|
||||||
|
// Test side effect push
|
||||||
|
i = arr.reduceRight<i32>(((prev: i32, current: i32, index: i32, array: Array<i32>): i32 => {
|
||||||
|
array.push(1); // push side effect should not affect this method by spec
|
||||||
|
return prev + current;
|
||||||
|
}), 0);
|
||||||
|
// array should be changed, but this method result should be calculated for old array length
|
||||||
|
assert(i == 6);
|
||||||
|
assert(arr.length == 8);
|
||||||
|
i = arr.reduceRight<i32>(((prev: i32, current: i32, index: i32, array: Array<i32>): i32 => prev + current), 0);
|
||||||
|
assert(i == 10);
|
||||||
|
|
||||||
|
arr.pop();
|
||||||
|
arr.pop();
|
||||||
|
arr.pop();
|
||||||
|
arr.pop();
|
||||||
|
|
||||||
|
// Test side effect pop
|
||||||
|
i = arr.reduceRight<i32>(((prev: i32, current: i32, index: i32, array: Array<i32>): i32 => {
|
||||||
|
array.pop(); // poped items should be reduced
|
||||||
|
return prev + current;
|
||||||
|
}), 0);
|
||||||
|
|
||||||
|
assert(i == 6);
|
||||||
|
assert(arr.length == 0);
|
||||||
|
|
||||||
|
arr.push(0);
|
||||||
|
arr.push(1);
|
||||||
|
arr.push(2);
|
||||||
|
arr.push(3);
|
||||||
|
|
||||||
// Array#sort //////////////////////////////////////////////////////////////////////////////////////
|
// Array#sort //////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// Checks if an array is properly sorted
|
// Checks if an array is properly sorted
|
||||||
|
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user