Sophisticated transformation operations including grouping, sorting, unique filtering, and batch processing.
Group stream values by a key function or property.
/**
* Group values by a key function or property name
* @param {Function|string} keySelector - Function to generate keys or property name
* @returns {Stream} Stream containing a single grouped object
*/
Stream.prototype.group(keySelector);Usage Examples:
const users = [
{name: 'Alice', role: 'admin'},
{name: 'Bob', role: 'user'},
{name: 'Charlie', role: 'admin'}
];
// Group by property name
_(users).group('role').toArray(console.log);
// {admin: [{name: 'Alice', role: 'admin'}, {name: 'Charlie', role: 'admin'}],
// user: [{name: 'Bob', role: 'user'}]}
// Group by function
_([1, 2, 3, 4, 5]).group(x => x % 2 === 0 ? 'even' : 'odd').toArray(console.log);
// {odd: [1, 3, 5], even: [2, 4]}Sort stream values using comparison functions.
/**
* Sort values using a comparison function
* @param {Function} compareFn - Comparison function (a, b) => number
* @returns {Stream} Stream with sorted values
*/
Stream.prototype.sortBy(compareFn);
/**
* Sort values lexically (ascending)
* @returns {Stream} Stream with sorted values
*/
Stream.prototype.sort();Usage Examples:
// Sort numbers descending
_([3, 1, 4, 1, 5]).sortBy((a, b) => b - a).toArray(console.log); // [5, 4, 3, 1, 1]
// Sort strings lexically
_(['banana', 'apple', 'cherry']).sort().toArray(console.log); // ['apple', 'banana', 'cherry']
// Sort objects by property
const products = [{name: 'Laptop', price: 999}, {name: 'Book', price: 29}];
_(products).sortBy((a, b) => a.price - b.price).toArray(console.log);
// [{name: 'Book', price: 29}, {name: 'Laptop', price: 999}]Remove duplicate values from streams.
/**
* Remove duplicate values using strict equality (===)
* @returns {Stream} Stream with unique values
*/
Stream.prototype.uniq();
/**
* Remove duplicate values using custom comparison function
* @param {Function} compareFn - Function to compare values (a, b) => boolean
* @returns {Stream} Stream with unique values
*/
Stream.prototype.uniqBy(compareFn);Usage Examples:
// Remove duplicate primitives
_([1, 2, 2, 3, 1, 4]).uniq().toArray(console.log); // [1, 2, 3, 4]
// Remove duplicate objects by property
const users = [
{id: 1, name: 'Alice'},
{id: 2, name: 'Bob'},
{id: 1, name: 'Alice'}
];
_(users).uniqBy((a, b) => a.id === b.id).toArray(console.log);
// [{id: 1, name: 'Alice'}, {id: 2, name: 'Bob'}]Group stream values into batches for processing.
/**
* Batch values into arrays of specified size
* @param {number} size - Maximum size of each batch
* @returns {Stream} Stream of arrays
*/
Stream.prototype.batch(size);
/**
* Batch values by time or count limits
* @param {number} ms - Maximum milliseconds to wait
* @param {number} count - Maximum number of items per batch
* @returns {Stream} Stream of arrays
*/
Stream.prototype.batchWithTimeOrCount(ms, count);Usage Examples:
// Batch by count
_([1, 2, 3, 4, 5, 6, 7]).batch(3).toArray(console.log);
// [[1, 2, 3], [4, 5, 6], [7]]
// Batch by time or count
const stream = _(function(push, next) {
push(null, 1);
push(null, 2);
setTimeout(() => push(null, 3), 50);
setTimeout(() => push(null, _.nil), 100);
});
stream.batchWithTimeOrCount(25, 3).each(console.log);
// [1, 2] (batched by time)
// [3] (final batch)Operations for processing string streams.
/**
* Split stream by newlines
* @returns {Stream} Stream of lines
*/
Stream.prototype.split();
/**
* Split stream by custom separator
* @param {string|RegExp} separator - Separator to split on
* @returns {Stream} Stream of split parts
*/
Stream.prototype.splitBy(separator);
/**
* Insert separator between stream values
* @param {*} separator - Value to insert between elements
* @returns {Stream} Stream with interspersed separator
*/
Stream.prototype.intersperse(separator);Usage Examples:
// Split by newlines
_(['line1\nline2', '\nline3']).split().toArray(console.log);
// ['line1', 'line2', 'line3']
// Split by custom separator
_(['a,b,c', 'd,e']).splitBy(',').toArray(console.log);
// ['a', 'b', 'c', 'd', 'e']
// Intersperse separator
_(['a', 'b', 'c']).intersperse(',').toArray(console.log);
// ['a', ',', 'b', ',', 'c']Extract portions of streams or modify positions.
/**
* Extract slice from start (inclusive) to end (exclusive)
* @param {number} start - Start index
* @param {number} end - End index
* @returns {Stream} Stream slice
*/
Stream.prototype.slice(start, end);
/**
* Get first n values
* @param {number} n - Number of values to take
* @returns {Stream} Stream with first n values
*/
Stream.prototype.take(n);
/**
* Skip first n values
* @param {number} n - Number of values to skip
* @returns {Stream} Stream without first n values
*/
Stream.prototype.drop(n);
/**
* Get first value
* @returns {Stream} Stream with first value
*/
Stream.prototype.head();
/**
* Get last value
* @returns {Stream} Stream with last value
*/
Stream.prototype.last();Usage Examples:
// Slice operations
_([1, 2, 3, 4, 5]).slice(1, 4).toArray(console.log); // [2, 3, 4]
_([1, 2, 3, 4, 5]).take(3).toArray(console.log); // [1, 2, 3]
_([1, 2, 3, 4, 5]).drop(2).toArray(console.log); // [3, 4, 5]
// Positioning
_([1, 2, 3]).head().toArray(console.log); // [1]
_([1, 2, 3]).last().toArray(console.log); // [3]Call methods on stream values.
/**
* Call a method on each stream value
* @param {string} methodName - Name of method to call
* @param {Array} args - Arguments to pass to method
* @returns {Stream} Stream of method results
*/
Stream.prototype.invoke(methodName, args);Usage Examples:
// Call method on strings
_([' hello ', ' world ']).invoke('trim', []).toArray(console.log);
// ['hello', 'world']
// Call method with arguments
_(['hello', 'world']).invoke('toUpperCase', []).toArray(console.log);
// ['HELLO', 'WORLD']