Browse Source

Initial commit; v1.0.0

Sven Slootweg 3 months ago
commit
90c3a2a083
4 changed files with 142 additions and 0 deletions
  1. 68 0
      README.md
  2. 33 0
      example.js
  3. 31 0
      index.js
  4. 10 0
      package.json

+ 68 - 0
README.md

@ -0,0 +1,68 @@
1
# generate-lookup-table
2
3
Generates a (fast!) lookup table or index from any array of items.
4
5
__When to use this:__ When you might otherwise be looping through an array *many times* (eg. using `Array#find`), trying to locate an item(s) with a particular property.
6
7
If you'd otherwise only loop through the array *once*, it's probably faster *not* to use this library, and just do the loop - building a lookup table, while still quite fast in the bigger picture, takes time.
8
9
## License, donations, and other boilerplate
10
11
Licensed under either the [WTFPL](http://www.wtfpl.net/txt/copying/) or [CC0](https://creativecommons.org/publicdomain/zero/1.0/), at your choice. In practice, that means it's more or less public domain, and you can do whatever you want with it. Giving credit is *not* required, but still very much appreciated! I'd love to [hear from you](mailto:admin@cryto.net) if this module was useful to you.
12
13
Creating and maintaining open-source modules is a lot of work. A donation is also not required, but much appreciated! You can donate [here](http://cryto.net/~joepie91/donate.html).
14
15
## Usage
16
17
```js
18
"use strict";
19
20
const generateLookupTable = require("generate-lookup-table");
21
22
// Thanks to https://gist.github.com/nanotaboada/6396437 for the sample data!
23
24
let items = [
25
	{ name: "Eloquent JavaScript, Second Edition", tags: [ "javascript", "No Starch Press" ] },
26
	{ name: "Learning JavaScript Design Patterns", tags: [ "javascript", "O'Reilly Media" ] },
27
	{ name: "Speaking JavaScript", tags: [ "javascript", "O'Reilly Media" ] },
28
	{ name: "Programming JavaScript Applications", tags: [ "javascript", "O'Reilly Media" ] },
29
	{ name: "Understanding ECMAScript 6", tags: [ "javascript", "No Starch Press" ] },
30
	{ name: "You Don't Know JS", tags: [ "javascript", "O'Reilly Media" ] },
31
	{ name: "Git Pocket Guide", tags: [ "git", "O'Reilly Media" ] },
32
	{ name: "Designing Evolvable Web APIs with ASP.NET", tags: [ "asp.net", "O'Reilly Media" ] },
33
];
34
35
let lookupTable = generateLookupTable(items, (item) => item.tags);
36
37
console.log(lookupTable.get("git"));
38
39
/* Output:
40
	[ { name: 'Git Pocket Guide', tags: [ 'git', 'O\'Reilly Media' ] } ]
41
*/
42
43
console.log(lookupTable.get("No Starch Press"));
44
45
/* Output:
46
	[ { name: 'Eloquent JavaScript, Second Edition',
47
		tags: [ 'javascript', 'No Starch Press' ] },
48
	{ name: 'Understanding ECMAScript 6',
49
		tags: [ 'javascript', 'No Starch Press' ] } ]
50
*/
51
```
52
53
## API
54
55
### generateLookupTable(items, keyFunction)
56
57
Generates a lookup table for the given set of `items`, using the `keyFunction` to determine what key(s) each item should be registered for.
58
59
- __items:__ The array of items to index.
60
- __keyFunction(item):__ A function that, given an `item` as its argument, returns the key(s) for that item. The function may return either a single key, an array of them, or nothing at all.
61
62
Returns a `Map` that maps from a key (as returned from the `keyFunction`) to all items that returned that particular key.
63
64
## Changelog
65
66
### v1.0.0 (February 21, 2020)
67
68
Initial release.

+ 33 - 0
example.js

@ -0,0 +1,33 @@
1
"use strict";
2
3
const generateLookupTable = require("./");
4
5
// Thanks to https://gist.github.com/nanotaboada/6396437 for the sample data!
6
7
let items = [
8
	{ name: "Eloquent JavaScript, Second Edition", tags: [ "javascript", "No Starch Press" ] },
9
	{ name: "Learning JavaScript Design Patterns", tags: [ "javascript", "O'Reilly Media" ] },
10
	{ name: "Speaking JavaScript", tags: [ "javascript", "O'Reilly Media" ] },
11
	{ name: "Programming JavaScript Applications", tags: [ "javascript", "O'Reilly Media" ] },
12
	{ name: "Understanding ECMAScript 6", tags: [ "javascript", "No Starch Press" ] },
13
	{ name: "You Don't Know JS", tags: [ "javascript", "O'Reilly Media" ] },
14
	{ name: "Git Pocket Guide", tags: [ "git", "O'Reilly Media" ] },
15
	{ name: "Designing Evolvable Web APIs with ASP.NET", tags: [ "asp.net", "O'Reilly Media" ] },
16
];
17
18
let lookupTable = generateLookupTable(items, (item) => item.tags);
19
20
console.log(lookupTable.get("git"));
21
22
/* Output:
23
	[ { name: 'Git Pocket Guide', tags: [ 'git', 'O\'Reilly Media' ] } ]
24
*/
25
26
console.log(lookupTable.get("No Starch Press"));
27
28
/* Output:
29
	[ { name: 'Eloquent JavaScript, Second Edition',
30
		tags: [ 'javascript', 'No Starch Press' ] },
31
	{ name: 'Understanding ECMAScript 6',
32
		tags: [ 'javascript', 'No Starch Press' ] } ]
33
*/

+ 31 - 0
index.js

@ -0,0 +1,31 @@
1
"use strict";
2
3
module.exports = function generateLookupTable(items, getKey) {
4
	let lookupTable = new Map();
5
6
	function setItem(key, value) {
7
		// TODO: Add a fast path for unique keys (no array wrapping), so that the index can contain both single items and arrays?
8
		if (lookupTable.has(key)) {
9
			lookupTable.get(key).push(value);
10
		} else {
11
			lookupTable.set(key, [ value ]);
12
		}
13
	}
14
15
	items.forEach((item) => {
16
		let key = getKey(item);
17
18
		if (key != null) {
19
			if (Array.isArray(key)) {
20
				// This item should be available under multiple keys
21
				for (let keyItem of key) {
22
					setItem(keyItem, item);
23
				}
24
			} else {
25
				setItem(key, item);
26
			}
27
		}
28
	});
29
30
	return lookupTable;
31
};

+ 10 - 0
package.json

@ -0,0 +1,10 @@
1
{
2
  "name": "generate-lookup-table",
3
  "description": "Generates a (fast!) lookup table or index from any array of items.",
4
  "keywords": [ "index", "lookup table", "map", "generate", "generator" ],
5
  "version": "1.0.0",
6
  "main": "index.js",
7
  "repository": "https://git.cryto.net/joepie91/generate-lookup-table.git",
8
  "author": "Sven Slootweg <admin@cryto.net>",
9
  "license": "WTFPL OR CC0-1.0"
10
}