index-array-by ============== [![NPM package][npm-img]][npm-url] [![Build Size][build-size-img]][build-size-url] [![Dependencies][dependencies-img]][dependencies-url] A utility function to index arrays by any criteria. `indexBy(list, keyAccessors, multiItem = true)` ## Quick start ``` import indexBy from 'index-array-by'; ``` or ``` const indexBy = require('index-array-by'); ``` or even ``` ``` ## Usage example Given an array ``` const people = [ { name: 'Mary', surname: 'Jane', age: 28 }, { name: 'John', surname: 'Smith', age: 24 }, { name: 'John', surname: 'Doe', age: 32 } ]; ``` Use `indexBy` to index it by a given attribute (string type `keyAccessor`) or any other custom criteria (function type `keyAccessor`). You can also pass an array of `keyAccessors` to retrieve a nested object recursively indexed by the multiple keys. Use the third parameter (`multiItem`) to indicate whether each key should point to a single item (unadvised if the keys are not unique) or an array of multiple items (default behavior). ``` indexBy(people, 'surname', false); // Result: { Doe: { name: 'John', age: 32 }, Jane: { name: 'Mary', age: 28 }, Smith: { name: 'John', age: 24 } } ``` ``` indexBy(people, 'name', true); // Result: { Mary: [ { surname: 'Jane', age: 28 } ], John: [ { surname: 'Smith', age: 24 }, { surname: 'Doe', age: 32 } ] } ``` ``` indexBy(people, ({ name, surname }) => `${surname}, ${name}`, false); // Result: { 'Jane, Mary': { name: 'Mary', surname: 'Jane', age: 28 }, 'Smith, John': { name: 'John', surname: 'Smith', age: 24 }, 'Doe, John': { name: 'John', surname: 'Doe', age: 32 } } ``` ``` indexBy(people, ['name', 'surname'], false)); // Result: { Mary: { Jane: { age: 28 }}, John: { Smith: { age: 24 }, Doe: { age: 32 }} } ``` ``` indexBy(people, ({ age }) => `${Math.floor(age / 10) * 10}s`, true); // Result: { '20s': [ { name: 'Mary', surname: 'Jane', age: 28 }, { name: 'John', surname: 'Smith', age: 24 }, ], '30s': [{ name: 'John', surname: 'Doe', age: 32 }] } ``` The `multiItem` parameter also accepts a transformation function with the method to reduce multiple items into a single one. In this case, it's keeping only the max age. ``` indexBy(people, 'name', items => Math.max(...items.map(item => item.age))); // Result: { John: 32, Mary: 28 } ``` A fourth optional parameter (`flattenKeys`) (default: `false`) allows you to receive a flat array structure instead of the default nested format, with each item formatted as `{ keys: [], vals: }`. ``` indexBy(people, ['name', 'surname'], true, true)); // Result: [ { keys: ['Mary', 'Jane'], vals: [{ age: 28 }] }, { keys: ['John', 'Smith'], vals: [{ age: 24 }] }, { keys: ['John', 'Doe'], vals: [{ age: 32 }] } ] ``` [npm-img]: https://img.shields.io/npm/v/index-array-by.svg [npm-url]: https://npmjs.org/package/index-array-by [build-size-img]: https://img.shields.io/bundlephobia/minzip/index-array-by.svg [build-size-url]: https://bundlephobia.com/result?p=index-array-by [dependencies-img]: https://img.shields.io/david/vasturiano/index-array-by.svg [dependencies-url]: https://david-dm.org/vasturiano/index-array-by