Observed since 20 Oct, 19:11 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
Functional utility library for modern TypeScript, ESM, ES6+
Modern utility library inspired by Lodash, built with ESM6 and TypeScript
Using npm:
npm install fishdash
Using yarn:
yarn add fishdash
Using pnpm:
pnpm add fishdash
Using bun:
bun add fishdash
Import specific functions (recommended for tree-shaking):
import { map, groupBy, pick } from 'fishdash';
Import all functions:
import fishdash from 'fishdash';
// or
import * as fishdash from 'fishdash';
import { map, groupBy, pick, deepMerge } from 'fishdash';
// Working with arrays
const users = [
{ id: 1, name: 'Alice', age: 25, department: 'Engineering' },
{ id: 2, name: 'Bob', age: 30, department: 'Engineering' },
{ id: 3, name: 'Carol', age: 28, department: 'Marketing' }
];
// Extract names
const names = map(users, user => user.name);
// ['Alice', 'Bob', 'Carol']
// Group by department
const byDepartment = groupBy(users, user => user.department);
// {
// Engineering: [{ id: 1, name: 'Alice', ... }, { id: 2, name: 'Bob', ... }],
// Marketing: [{ id: 3, name: 'Carol', ... }]
// }
// Pick specific properties
const summary = pick(users[0], ['id', 'name']);
// { id: 1, name: 'Alice' }
// Deep merge objects
const config = deepMerge(
{ api: { timeout: 5000 } },
{ api: { retries: 3 }, debug: true }
);
// { api: { timeout: 5000, retries: 3 }, debug: true }
map(object, mapper)Transforms each value in an object using the mapper function and returns an array.
const users = { user1: { name: 'Alice' }, user2: { name: 'Bob' } };
const names = map(users, user => user.name);
// ['Alice', 'Bob']
groupBy(array, iteratee)Groups array elements by the result of running each element through iteratee.
const inventory = [
{ name: 'apple', category: 'fruit' },
{ name: 'carrot', category: 'vegetable' },
{ name: 'banana', category: 'fruit' }
];
const grouped = groupBy(inventory, item => item.category);
// {
// fruit: [{ name: 'apple', category: 'fruit' }, { name: 'banana', category: 'fruit' }],
// vegetable: [{ name: 'carrot', category: 'vegetable' }]
// }
sortBy(array, iteratee)Sorts array elements by the result of running each element through iteratee.
const users = [
{ name: 'Charlie', age: 30 },
{ name: 'Alice', age: 25 },
{ name: 'Bob', age: 35 }
];
const sortedByAge = sortBy(users, user => user.age);
// [{ name: 'Alice', age: 25 }, { name: 'Charlie', age: 30 }, { name: 'Bob', age: 35 }]
uniq(array) & uniqBy(array, iteratee)Removes duplicate values from an array.
// Simple deduplication
const numbers = uniq([1, 2, 2, 3, 1, 4]);
// [1, 2, 3, 4]
// Deduplication by property
const users = [
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' },
{ id: 1, name: 'Alice' }
];
const uniqueUsers = uniqBy(users, user => user.id);
// [{ id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }]
count(array, predicate) & countBy(array, iteratee)Counts elements in an array.
// Count with predicate
const numbers = [1, 2, 3, 4, 5];
const evenCount = count(numbers, n => n % 2 === 0);
// 2
// Count by grouping
const fruits = ['apple', 'banana', 'apple', 'orange'];
const counts = countBy(fruits, fruit => fruit);
// { apple: 2, banana: 1, orange: 1 }
pick(object, keys) & pickBy(object, predicate)Selects specific properties from an object.
const user = { id: 1, name: 'Alice', email: 'alice@example.com', password: 'secret' };
// Pick specific keys
const publicInfo = pick(user, ['id', 'name', 'email']);
// { id: 1, name: 'Alice', email: 'alice@example.com' }
// Pick by predicate
const nonSensitive = pickBy(user, (value, key) => key !== 'password');
// { id: 1, name: 'Alice', email: 'alice@example.com' }
omit(object, keys) & omitBy(object, predicate)Excludes specific properties from an object.
const user = { id: 1, name: 'Alice', email: 'alice@example.com', password: 'secret' };
// Omit specific keys
const publicInfo = omit(user, ['password']);
// { id: 1, name: 'Alice', email: 'alice@example.com' }
// Omit by predicate
const withoutEmpty = omitBy({ a: 1, b: '', c: 3, d: null }, value => !value);
// { a: 1, c: 3 }
mapValues(object, iteratee)Transforms values in an object while preserving keys.
const scores = { math: 85, science: 92, english: 78 };
const grades = mapValues(scores, score => score >= 90 ? 'A' : score >= 80 ? 'B' : 'C');
// { math: 'B', science: 'A', english: 'C' }
keyBy(array, iteratee)Creates an object keyed by the result of running each array element through iteratee.
const users = [
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' }
];
const usersById = keyBy(users, user => user.id);
// { 1: { id: 1, name: 'Alice' }, 2: { id: 2, name: 'Bob' } }
deepMerge(...objects)Recursively merges objects, concatenating arrays.
const obj1 = {
api: { timeout: 5000 },
features: ['auth']
};
const obj2 = {
api: { retries: 3 },
features: ['logging'],
debug: true
};
const merged = deepMerge(obj1, obj2);
// {
// api: { timeout: 5000, retries: 3 },
// features: ['auth', 'logging'],
// debug: true
// }
fromPairs(pairs) & toPairs(object)Converts between arrays of key-value pairs and objects.
// From pairs to object
const pairs = [['a', 1], ['b', 2], ['c', 3]];
const obj = fromPairs(pairs);
// { a: 1, b: 2, c: 3 }
// From object to pairs
const object = { x: 1, y: 2 };
const converted = toPairs(object);
// [['x', 1], ['y', 2]]
set(object, path, value) & setProps(object, props)Sets values in objects.
// Set nested property
const user = {};
set(user, 'profile.name', 'Alice');
// { profile: { name: 'Alice' } }
// Set multiple properties
const updated = setProps(user, { age: 25, 'profile.email': 'alice@example.com' });
// { profile: { name: 'Alice', email: 'alice@example.com' }, age: 25 }
pad(string, length, chars)Pads a string to a specified length.
const padded = pad('hello', 10, '-');
// '--hello---'
any(array, predicate) & every(array, predicate)Tests array elements against a predicate.
const numbers = [1, 2, 3, 4, 5];
const hasEven = any(numbers, n => n % 2 === 0);
// true
const allPositive = every(numbers, n => n > 0);
// true
maxBy(array, iteratee) & minBy(array, iteratee)Finds maximum/minimum values by a given criteria.
const users = [
{ name: 'Alice', age: 25 },
{ name: 'Bob', age: 30 },
{ name: 'Carol', age: 22 }
];
const oldest = maxBy(users, user => user.age);
// { name: 'Bob', age: 30 }
const youngest = minBy(users, user => user.age);
// { name: 'Carol', age: 22 }
Fishdash includes comprehensive TypeScript definitions:
// Generic mapper function type
type ObjectMapper<T> = (value: T, key?: string | number) => any;
// Object-like type for flexible input
type ObjectLike<T> = Record<string | number, T>;
// All functions are properly typed for intellisense and type safety
const users: User[] = [/* ... */];
const names: string[] = map(users, user => user.name); // Type-safe!
Fishdash is built with tree-shaking in mind. Import only what you need:
// ✅ Good - only imports the functions you use
import { map, filter } from 'fishdash';
// ❌ Avoid - imports the entire library
import fishdash from 'fishdash';
const result = fishdash.map(/* ... */);
Fishdash supports all modern browsers that support ES6+ features:
Fishdash is optimized for performance while maintaining readability:
We welcome contributions! Please follow these steps:
git checkout -b feature/amazing-feature)npm test)git commit -m 'Add some amazing feature')git push origin feature/amazing-feature)Please read our Contributing Guide for detailed information.
MIT © Igor Suvorov
fishdash - Swimming in utilities 🐠
Download counts and popularity will appear here as the collector receives them.
This describes our collected data; it is not a security assessment.
Observed since 20 Oct, 19:11 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
package:5f2e2788c7f0c4d2561a65d495109ed18ccd7d824413bb88bcee05548f4403bd