Skip to content

Instantly share code, notes, and snippets.

@tlux
Last active March 2, 2023 09:41
Show Gist options
  • Save tlux/a24c1154852d13cac0faa557176470ac to your computer and use it in GitHub Desktop.
Save tlux/a24c1154852d13cac0faa557176470ac to your computer and use it in GitHub Desktop.
TypeScript helper to find a value in an array, inspired by Elixir's Enum.find_value
import findValue, { FindValueFilterMapper } from './findValue';
describe('findValue(value, predicate)', () => {
const FILTER_MAPPER: FindValueFilterMapper<number, string> = (v) => {
if (v < 0) {
return [true, 'negative'];
}
if (v % 2 === 1) {
return [false, 'odd'];
}
if (v % 2 === 0) {
return [true, 'even'];
}
return false;
};
it('returns found value', () => {
expect(findValue([-1, 2], FILTER_MAPPER)).toEqual('negative');
expect(findValue([2, 1], FILTER_MAPPER)).toEqual('even');
expect(findValue([1, 2, 3], FILTER_MAPPER)).toEqual('even');
expect(findValue([1, 3, 5, 6], FILTER_MAPPER)).toEqual('even');
});
it('returns undefined when not found', () => {
expect(findValue([1, 3, 5], FILTER_MAPPER)).toBeUndefined();
expect(findValue([], FILTER_MAPPER)).toBeUndefined();
});
});
export type FindValueFilterMapper<T, U> = (value: T, index: number) => [boolean, U] | false;
/**
* Finds a value in an array and returns that particular value.
*
* @param array The array to search in
*
* @param filterMapper A predicate returning a tuple with the first item indicating
* that the value has been found and the second item being the value itself.
*
* @returns The value as returned by the predicate or `undefined`.
*/
export default function findValue<T, U>(
array: T[],
filterMapper: FindValueFilterMapper<T, U>,
) {
for (let i = 0; i < array.length; i += 1) {
const res = filterMapper(array[i], i);
if (res !== false) {
const [found, value] = res;
if (found) {
return value;
}
}
}
return undefined;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment