# core/converters/base.converter.ts

> 19 lines of code and 5 definitions.

Tree: Bane's Lab Build Scripts
Language: typescript
Layer: processing
Canonical: https://banes-lab.com/anatomy/build-scripts#file-build-scripts-core-converters-base-converter-ts
Source text: https://banes-lab.com/source/build-scripts/core/converters/base.converter.ts.txt

Listed in [core/converters](https://banes-lab.com/api/source/build-scripts/core/converters.md), after [core/converters/architecture.index.converter.ts](https://banes-lab.com/source/build-scripts/core/converters/architecture.index.converter.ts.md) and before [core/converters/baseline.converter.ts](https://banes-lab.com/source/build-scripts/core/converters/baseline.converter.ts.md).

## Definitions

- `groupedBy` (lexical_declaration, line 1, exported)
- `groups` (lexical_declaration, line 5, exported)
- `key` (lexical_declaration, line 7, exported)
- `held` (lexical_declaration, line 8, exported)
- `orNull` (lexical_declaration, line 18, exported)

## Contained in

- [core/converters](https://banes-lab.com/anatomy/build-scripts/folder-build-scripts-core-converters.md)

## Source

```typescript
export const groupedBy = function groupedBy<T>(
    items: readonly T[],
    keyOf: (item: T) => string,
): ReadonlyMap<string, T[]> {
    const groups = new Map<string, T[]>();
    for (const item of items) {
        const key = keyOf(item);
        const held = groups.get(key);
        if (held === undefined) {
            groups.set(key, [item]);
        } else {
            held.push(item);
        }
    }
    return new Map([...groups.entries()].sort(([left], [right]) => left.localeCompare(right)));
};

export const orNull = function orNull(value?: string): string | null {
    return value === undefined || value.length === 0 ? null : value;
};
```
