Skip to content

Commit

Permalink
feat(arrays): add arraySeq(), arrayIterator() & tests
Browse files Browse the repository at this point in the history
  • Loading branch information
postspectacular committed Nov 15, 2019
1 parent 541e9c8 commit d94df57
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 0 deletions.
2 changes: 2 additions & 0 deletions packages/arrays/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@ export * from "./ensure-iterable";
export * from "./find";
export * from "./fuzzy-match";
export * from "./is-sorted";
export * from "./iterator";
export * from "./peek";
export * from "./quicksort";
export * from "./seq";
export * from "./shuffle";
export * from "./starts-with";
export * from "./swap";
Expand Down
28 changes: 28 additions & 0 deletions packages/arrays/src/iterator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { Nullable } from "@thi.ng/api";

/**
* Returns iterator of nullable array w/ optional index range support
* and/or reverse iteration order. The default range covers the entire
* array.
*
* @remarks
* If `start` > `end`, yields values in reverse order. No bounds
* checking is performed.
*
* @param buf - array or null
* @param start - start index
* @param end - end index (excluded)
*/
export function* arrayIterator<T>(
buf: Nullable<ArrayLike<T>>,
start = 0,
end?: number
) {
if (!buf) return;
start = start;
end === undefined && (end = buf.length);
const step = start <= end ? 1 : -1;
for (; start !== end; start += step) {
yield buf[start];
}
}
30 changes: 30 additions & 0 deletions packages/arrays/src/seq.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { ISeq, Nullable } from "@thi.ng/api";

/**
* Returns a zero-copy {@link @thi.ng/api#ISeq} for the given array and
* optionally defined index range.
*
* @remarks
* See {@link arrayIterator} for related functionality.
*
* @param buf - array
* @param start - start index
* @param end - end index (excluded)
*/
export const arraySeq = <T>(
buf: Nullable<ArrayLike<T>>,
start = 0,
end?: number
): ISeq<T> => ({
first() {
if (!buf) return;
end === undefined && (end = buf.length);
return start < end! ? buf[start] : undefined;
},
next() {
if (!buf) return;
end === undefined && (end = buf.length);
const i = start + 1;
return i < end! ? arraySeq<T>(buf, i, end) : undefined;
}
});
13 changes: 13 additions & 0 deletions packages/arrays/test/iterator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import * as assert from "assert";
import { arrayIterator } from "../src";

describe("arrayIterator", () => {
it("basics", () => {
assert.deepEqual([...arrayIterator(null)], []);
assert.deepEqual([...arrayIterator([])], []);
assert.deepEqual([...arrayIterator([1])], [1]);
assert.deepEqual([...arrayIterator([1, 2, 3, 4], 2)], [3, 4]);
assert.deepEqual([...arrayIterator([1, 2, 3, 4], 2, 3)], [3]);
assert.deepEqual([...arrayIterator([1, 2, 3, 4], 3, -1)], [4, 3, 2, 1]);
});
});
21 changes: 21 additions & 0 deletions packages/arrays/test/seq.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import * as assert from "assert";
import { arraySeq } from "../src";

describe("arraySeq", () => {
it("basics", () => {
assert.notEqual(arraySeq(null), undefined);
assert.equal(arraySeq(null).first(), undefined);
assert.equal(arraySeq(null).next(), undefined);
assert.equal(arraySeq([]).first(), undefined);
assert.equal(arraySeq([]).next(), undefined);
assert.equal(arraySeq([1]).first(), 1);
assert.equal(arraySeq([1]).next(), undefined);
assert.equal(arraySeq([1, 2]).first(), 1);
// prettier-ignore
assert.equal(arraySeq([1, 2]).next()!.first(), 2);
// prettier-ignore
assert.equal(arraySeq([1, 2]).next()!.next(), undefined);
// prettier-ignore
assert.equal(arraySeq([1, 2, 3]).next()!.next()!.first(), 3);
});
});

0 comments on commit d94df57

Please sign in to comment.