Skip to content

Commit

Permalink
feat(array): add mapify
Browse files Browse the repository at this point in the history
  • Loading branch information
Kimbrian Marshall committed Jul 2, 2024
1 parent 80655f3 commit 74b0bbd
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 0 deletions.
28 changes: 28 additions & 0 deletions benchmarks/array/mapify.bench.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import * as _ from 'radashi'
import { bench } from 'vitest'

describe('mapify', () => {
bench('with full list and identity value function', () => {
const list = [
{ id: 'a', word: 'hello' },
{ id: 'b', word: 'bye' },
{ id: 'c', word: 'oh' },
{ id: 'd', word: 'hey' },
{ id: 'e', word: 'ok' },
]
_.objectify(
list,
x => x.id,
x => x,
)
})

bench('with empty list', () => {
_.objectify(
[],
(x: any) => x.id,
x => x,
)
})
})

38 changes: 38 additions & 0 deletions docs/array/mapify.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
---
title: mapify
group: "Array"
description: Convert an array to a map
---

## Basic usage

Given an array of items, create a map with keys and values mapped by given
functions. First argument is the array to map. The second argument is the
function to determine the key for each item. The third argument is optional and
determines the value for each item.

```ts
import * as _ from "radashi";

const fish = [
{
name: "Marlin",
weight: 105,
},
{
name: "Bass",
weight: 8,
},
{
name: "Trout",
weight: 13,
},
];

_.mapify(fish, f => f.name); // => Map(3) {'Marlin' => { name: 'Marlin', weight: 105 }, 'Bass' => { name: 'Bass', weight: 8 }, 'Trout' => { name: 'Trout', weight: 13 }}
_.mapify(
fish,
f => f.name,
f => f.weight
); // => Map(3) { 'Marlin' => 105, 'Bass' => 8, 'Trout' => 13 }
```
9 changes: 9 additions & 0 deletions src/array/mapify.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export function mapify<T, Key, Value = T>(
array: readonly T[],
getKey: (item: T) => Key,
getValue: (item: T) => Value = item => item as unknown as Value,
): Map<Key, Value> {
const map: Map<Key, Value> = new Map();
array.forEach(item => map.set(getKey(item), getValue(item)))
return map;
}
2 changes: 2 additions & 0 deletions src/mod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export * from './array/intersects.ts'
export * from './array/iterate.ts'
export * from './array/last.ts'
export * from './array/list.ts'
export * from './array/mapify.ts'
export * from './array/max.ts'
export * from './array/merge.ts'
export * from './array/min.ts'
Expand Down Expand Up @@ -105,3 +106,4 @@ export * from './typed/isPrimitive.ts'
export * from './typed/isPromise.ts'
export * from './typed/isString.ts'
export * from './typed/isSymbol.ts'

36 changes: 36 additions & 0 deletions tests/array/mapify.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import * as _ from 'radashi'

describe('mapify', () => {
const list = [
{ id: 'a', word: 'hello' },
{ id: 'b', word: 'bye' },
{ id: 'c', word: 'oh' },
{ id: 'd', word: 'hey' },
{ id: 'e', word: 'ok' },
]
test('returns correct map of values', () => {
const result = _.mapify(
list,
x => x.id,
x => x,
)
expect(result).toBeTypeOf(typeof new Map())
expect(result.size).toBe(5)
expect(result.get("a")?.word).toBe('hello')
expect(result.get("b")?.word).toBe('bye')
})
test('does not fail on empty input list', () => {
const result = _.mapify(
[],
(x: any) => x.id,
x => x,
)
expect(result).toBeTypeOf(typeof new Map())
})
test('defaults value to array item', () => {
const result = _.mapify(list.slice(0, 1), x => x.id)
expect(result).toBeTypeOf(typeof new Map())
expect(result.size).toBe(1)
expect(result.get("a")?.word).toBe('hello')
})
})

0 comments on commit 74b0bbd

Please sign in to comment.