Skip to content

Commit 42d6d1a

Browse files
authored
Patch v0.1.6 (#24)
Patch v0.1.6 with cleaner JS examples and README updates
1 parent f27ffbd commit 42d6d1a

File tree

7 files changed

+91
-42
lines changed

7 files changed

+91
-42
lines changed

README.md

Lines changed: 38 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,41 @@
11
# n-tuple-array
22

3-
Get a **`configurable`** amount of items when iterating over a JavaScript array, instead of a single item that arrays provide per iteration, by default.
3+
Get a **`configurable`** amount of items when iterating over a JavaScript array, instead of a single item that arrays provide per iteration, by default.
4+
5+
Put differently, easily and safely retrieve a configurable number of items from an array, without having to manipulate array bounds or indices.
46

57

68
## Motivation
79

810
Imagine that you received a large collection of coordinates (latitude and longitude), but they were sent
911
as a flat array of values to speed up the data transfer.
1012

11-
`n-tuple-array` can help you get out the coordinates in pairs (i.e their logical representation), such that you'd go
13+
`n-tuple-array` can help you get out the coordinates in pairs (i.e their logical representation), such that you'd __easily__ go
1214

1315
**from**
1416
```json
1517
// flat coordinates
1618
["5.7225", "-9.6273", "2.68452", "-30.9501", ...]
1719
```
1820

19-
**to**
21+
**to**
22+
```json
23+
// coordinates in pairs
24+
[["5.7225", "-9.6273"], ["2.68452", "-30.9501"], ...]
25+
```
26+
27+
**using**
2028
```javascript
2129
// the iterable will generate pairs by default
2230
const coordsIterable = tuplesFromArray({ list: flatCoords });
2331

24-
// using for..of, get pairs as ["5.7225", "-9.6273"] ...
32+
// with for..of, get pairs as ["5.7225", "-9.6273"] ...
2533
for (const pair of coordsIterable) {
2634
console.log(pair);
2735
}
2836

29-
// OR manipulate pairs with regular array
37+
// OR
38+
// manipulate pairs with regular array
3039
// functions like map, filter, forEach ...
3140
const coordsInPairs = Array.from(coordsIterable);
3241
console.log(Array.isArray(coordsInPairs)); // true
@@ -41,29 +50,6 @@ coordsInPairs
4150
});
4251
```
4352

44-
### Some Real World Examples
45-
46-
#### 1. Wole Joko
47-
48-
I first tried my hands on this concept when [fleshing out wole-joko](https://github.com/chalu/wole-joko/blob/dev/src/js/utils.js#L57-L92), which strated as a _live coding task_ I was asked to do in an engineering manager interview :man_shrugging
49-
It was a simulation of people entering an event hall to get seated, but **only two** could get in at a time - https://wole-joko.netlify.app/
50-
51-
#### 2. Execute max of `N` async tasks
52-
53-
![](./assets/the-dax-js-challenge.png "JS challenge by @thdxr")
54-
55-
> The below was adapted for more concise terminal output
56-
57-
`n-tuple-array` solution. View [code here](https://github.com/chalu/n-tuple-array/blob/main/src/examples/classic.ts#L6-L40) <br>
58-
![](./assets/demo-classic.png "n-tuple-array solution")
59-
<br> <br>
60-
61-
`n-tuple-array` solution demo <br>
62-
`n-tuple-array` solution demo <br>
63-
![](./assets/ntuple-array-demo-optimized.gif "n-tuple-array solution demo")
64-
65-
66-
6753
## Setup & Usage
6854

6955
```bash
@@ -72,7 +58,6 @@ npm install @chalu/n-tuple-array
7258

7359
```javascript
7460
const { tuplesFromArray } = require('@chalu/n-tuple-array');
75-
const { tuplesFromArray } = require('@chalu/n-tuple-array');
7661

7762
// some setup
7863
const numbers = Array.from({length: 100}, (_, i) => i + 1);
@@ -86,16 +71,39 @@ const isEven = (item) => {
8671
return true;
8772
};
8873

89-
// use the lib
74+
// use the lib, get batches of <= 5 nums
75+
// from the collection in numbers above
9076
const quintetIterator = tuplesFromArray({
9177
list: numbers, maxItems: 5, match: isEven
9278
});
9379

80+
// since quintetIterator uses the isEven match
81+
// function, give us only even numbers in fives
9482
for (const quintet of quintetIterator) {
9583
// prints [ 2, 4, 6, 8, 10 ] ... [ 92, 94, 96, 98, 100 ]
9684
console.log(quintet);
9785
}
9886
```
9987

88+
### Some Real World Examples
89+
90+
#### 1. Wole Joko
91+
92+
I first tried my hands on this concept when [fleshing out wole-joko](https://github.com/chalu/wole-joko/blob/dev/src/js/utils.js#L57-L92), which strated as a _live coding task_ I was asked to do in an engineering manager interview :man_shrugging
93+
It was a simulation of people entering an event hall to get seated, but **only two** could get in at a time - https://wole-joko.netlify.app/
94+
95+
#### 2. Execute max of `N` async tasks at the same time
96+
97+
![](./assets/the-dax-js-challenge.png "JS challenge by @thdxr")
98+
99+
> The below was adapted for more concise terminal output
100+
101+
`n-tuple-array` solution. View [code here](https://github.com/chalu/n-tuple-array/blob/main/src/examples/classic.ts#L6-L40) <br>
102+
![](./assets/demo-classic.png "n-tuple-array solution")
103+
<br> <br>
104+
105+
`n-tuple-array` solution demo <br>
106+
![](./assets/ntuple-array-demo-optimized.gif)
107+
100108
See more examples in [src/examples](./src/examples/)
101109

assets/the-dax-js-challenge.png

-8.51 KB
Loading

dist/cjs/types/index.d.ts

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,53 @@
1-
type Item<T> = T | undefined;
2-
type Value<T> = Array<Item<T>>;
31
export type Matcher<T> = (item: T | unknown) => boolean;
42
export type TupleConfig<T> = {
3+
/**
4+
* The input array to use
5+
*/
56
list: T[];
7+
/**
8+
* The max number of items to return from the input array, per iteration
9+
* @defaultValue 2
10+
*/
611
maxItems?: number;
12+
/**
13+
* When provided, a function used to determine which items in the input array
14+
* are eligible to be included, per iteration
15+
*/
716
match?: Matcher<T>;
817
};
18+
/**
19+
* An exception than can be thrown if there is no input array, `maxItems` is <= 0 or is not
20+
* a number, or `match` is not a function
21+
*/
922
export declare class InvalidInvocationParameterError extends Error {
1023
}
11-
export declare const tuplesFromArray: <T>(config: TupleConfig<T>) => Iterable<Value<T>>;
24+
/**
25+
* Returns an iterable iterator that ouputs a configured
26+
* list of items when iterating over a given array
27+
*
28+
* @typeParam T - Type of items the input list contains
29+
*
30+
* @param config - An object to indicate the input array `config.list`, and set the
31+
* max size of items per interation `config.maxItems`. You can also optionally specify `config.match`
32+
* as a function that should return true to filter in items from the input array
33+
* (or false to filter them out) when deciding what items is to be included per iteration
34+
*
35+
* @function
36+
* @throws InvalidInvocationParameterError
37+
* This exception is thrown if there is no input array, `maxItems` is <= 0 or is not
38+
* a number, or `match` is not a function
39+
*
40+
* @returns an IterableIterator
41+
*
42+
* @example
43+
* Here is an example that will get max of 3 items from
44+
* each iteration on the returned iterable
45+
* ```javascript
46+
* const iterable = tuplesFromArray({
47+
* list:[], maxSize: 3, match: (itm) => !!itm
48+
* });
49+
* ```
50+
*/
51+
export declare const tuplesFromArray: <T>(config: TupleConfig<T>) => IterableIterator<(T | undefined)[]>;
1252
export default tuplesFromArray;
1353
//# sourceMappingURL=index.d.ts.map

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@chalu/n-tuple-array",
3-
"version": "0.1.6",
4-
"description": "Get a specified amount of items when iterating over a JavaScript array, instead of just a single item that arrays provide!",
3+
"version": "0.1.7",
4+
"description": "Configure and get a specified amount of items when iterating over a JavaScript array.",
55
"main": "./dist/cjs/index.js",
66
"module": "dist/esm/index.mjs",
77
"types": "./dist/cjs/types/index.d.ts",

src/examples/js/concurrent.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ const processTask = async (todo, batchId) => {
1414
};
1515

1616
const executeConcurrent = async (todos, maxBatchSize) => {
17+
console.log(`\ndo <= ${maxBatchSize} of ${todos.length} tasks (concurrently), at any given time\n`);
1718
const done = [];
1819
const todosCopy = todos.slice();
1920
const worker = async (_, batchIndex) => {
@@ -35,5 +36,5 @@ const executeConcurrent = async (todos, maxBatchSize) => {
3536
const maxTasksPerTime = 2;
3637

3738
const allDone = await executeConcurrent(tasks, maxTasksPerTime);
38-
console.log(allDone);
39+
console.log('\n', allDone);
3940
})();

src/examples/js/with-lib.mjs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,13 @@ const processTask = async (todo, batchId) => {
1616
};
1717

1818
const executeWitLibrary = async (todos, maxBatchSize) => {
19-
console.log(`do <= ${maxBatchSize} of ${todos.length} tasks, at any given time`);
19+
console.log(`\ndo <= ${maxBatchSize} of ${todos.length} tasks, at any given time (with library)`);
2020
const done = [];
2121

2222
let batchIndex = 1;
2323
const todosBatchIterable = tuplesFromArray({list: todos, maxItems: maxBatchSize});
2424
for (const batch of todosBatchIterable) {
25-
console.log(`----- starting batch [${batchIndex}], ${batch.length} todos`);
25+
console.log(`\n----- starting batch [${batchIndex}], ${batch.length} todos`);
2626
const results = await Promise.allSettled(
2727
batch.map(todo => processTask(todo, batchIndex)),
2828
);
@@ -39,5 +39,5 @@ const executeWitLibrary = async (todos, maxBatchSize) => {
3939
const maxTasksPerTime = 2;
4040

4141
const allDone = await executeWitLibrary(tasks, maxTasksPerTime);
42-
console.log(allDone);
42+
console.log('\n', allDone);
4343
})();

src/examples/js/without-lib.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,15 @@ const processTask = async (todo, batchId) => {
1515

1616
// Everywhere start/end is used is repititive and error prone
1717
const executeWithoutLibrary = async (todos, maxBatchSize) => {
18-
console.log(`do <= ${maxBatchSize} of ${todos.length} tasks, at any given time`);
18+
console.log(`\ndo <= ${maxBatchSize} of ${todos.length} tasks, at any given time (no library)`);
1919
const done = [];
2020

2121
let start = 0;
2222
let end = start + maxBatchSize;
2323
let batchIndex = 1;
2424
let batch = todos.slice(start, end);
2525
while (batch.length > 0) {
26-
console.log(`----- starting batch [${batchIndex}], ${batch.length} todos`);
26+
console.log(`\n----- starting batch [${batchIndex}], ${batch.length} todos`);
2727
const results = await Promise.allSettled(
2828
batch.map(todo => processTask(todo, batchIndex)),
2929
);
@@ -48,5 +48,5 @@ const executeWithoutLibrary = async (todos, maxBatchSize) => {
4848
const maxTasksPerTime = 2;
4949

5050
const allDone = await executeWithoutLibrary(tasks, maxTasksPerTime);
51-
console.log(allDone);
51+
console.log('\n', allDone);
5252
})();

0 commit comments

Comments
 (0)