|
8 | 8 | * @returns {*} Anything that will be the object entry value
|
9 | 9 | */
|
10 | 10 |
|
| 11 | +/** |
| 12 | + * @typedef asyncValueGenerator |
| 13 | + * @type {function} |
| 14 | + * @async |
| 15 | + * @param {string} value Original array entry |
| 16 | + * @param {number} index Index of the array entry (starts at 0) |
| 17 | + * @returns {*} Anything that will be the object entry value |
| 18 | + */ |
| 19 | + |
| 20 | +const emptyReturn = {} |
| 21 | + |
11 | 22 | /**
|
12 | 23 | * Converts an array to an object with static keys and customizable values
|
13 | 24 | * @example
|
14 | 25 | * import arrayToObjectKeys from "array-to-object-keys"
|
15 |
| - * arrayToObjectKeys(["a", "b"]) |
16 |
| - * // {a: null, b: null} |
| 26 | + * let result = arrayToObjectKeys(["a", "b"]) |
| 27 | + * result = {a: null, b: null} |
17 | 28 | * @example
|
18 | 29 | * import arrayToObjectKeys from "array-to-object-keys"
|
19 |
| - * arrayToObjectKeys(["a", "b"], "value") |
20 |
| - * // {a: "value", b: "value"} |
| 30 | + * let result = arrayToObjectKeys(["a", "b"], "value") |
| 31 | + * result = {a: "value", b: "value"} |
21 | 32 | * @example
|
22 | 33 | * import arrayToObjectKeys from "array-to-object-keys"
|
23 |
| - * arrayToObjectKeys(["a", "b"], (key, index) => `value for ${key} #${index + 1}`) |
24 |
| - * // {a: "value for a #1", b: "value for b #2"} |
| 34 | + * let result = arrayToObjectKeys(["a", "b"], (key, index) => `value for ${key} #${index + 1}`) |
| 35 | + * result = {a: "value for a #1", b: "value for b #2"} |
25 | 36 | * @function
|
26 | 37 | * @param {string[]} array Keys for the generated object
|
27 | 38 | * @param {valueGenerator|*} [valueGenerator=null] Optional function that sets the object values based on key and index
|
28 | 39 | * @returns {object<string, *>} A generated object based on the array input
|
29 | 40 | */
|
30 | 41 | export default (array, valueGenerator = null) => {
|
31 |
| - if (!Array.isArray(array)) { |
32 |
| - return {} |
| 42 | + if (!Array.isArray(array) || !array.length) { |
| 43 | + return emptyReturn |
33 | 44 | }
|
34 | 45 | const object = {}
|
35 | 46 | if (typeof valueGenerator === "function") {
|
36 |
| - let index = 0 |
| 47 | + array.forEach((key, index) => { |
| 48 | + object[key] = valueGenerator(key, index) |
| 49 | + }) |
| 50 | + } else { |
37 | 51 | for (const value of array) {
|
38 |
| - object[value] = valueGenerator(value, index) |
39 |
| - index++ |
| 52 | + object[value] = valueGenerator |
| 53 | + } |
| 54 | + } |
| 55 | + return object |
| 56 | +} |
| 57 | + |
| 58 | +/** |
| 59 | + * Converts an array to an object with static keys and customizable values |
| 60 | + * @example |
| 61 | + * import fs from "fs" |
| 62 | + * import path from "path" |
| 63 | + * import {parallel} from "array-to-object-keys" |
| 64 | + * const keys = ["license", "readme", "package", ".travis", "not-here"] |
| 65 | + * const valueGenerator = async name => { |
| 66 | + * const files = await fs.promises.readdir(path.resolve(__dirname, "..")) |
| 67 | + * for (const file of files) { |
| 68 | + * if (file.startsWith(`${name}.`)) { |
| 69 | + * const stat = await fs.promises.stat(path.resolve(__dirname, "..", file), "utf8") |
| 70 | + * return stat.size |
| 71 | + * } |
| 72 | + * } |
| 73 | + * return null |
| 74 | + * } |
| 75 | + * let result = await parallel(keys, valueGenerator) |
| 76 | + * result = { ".travis": 1672, license: 1099, package: 1948, readme: 132, "not-here": null } |
| 77 | + * @function |
| 78 | + * @param {string[]} array Keys for the generated object |
| 79 | + * @param {asyncValueGenerator|*} [valueGenerator=null] Async function that sets the object values based on key and index |
| 80 | + * @returns {object<string, *>} A generated object based on the array input |
| 81 | + */ |
| 82 | +export const parallel = async (array, valueGenerator = null) => { |
| 83 | + if (!Array.isArray(array) || !array.length) { |
| 84 | + return emptyReturn |
| 85 | + } |
| 86 | + const object = {} |
| 87 | + if (typeof valueGenerator === "function") { |
| 88 | + for (const key of array) { |
| 89 | + object[key] = null // Setting object keys synchronously to ensure order |
40 | 90 | }
|
| 91 | + const jobs = array.map(async (key, index) => { |
| 92 | + const value = await valueGenerator(key, index) |
| 93 | + object[key] = value |
| 94 | + }) |
| 95 | + await Promise.all(jobs) |
41 | 96 | } else {
|
42 | 97 | for (const value of array) {
|
43 | 98 | object[value] = valueGenerator
|
|
0 commit comments