Remeda

website·Indexed 32 days ago

https://remedajs.com

A fully typed library of functional utilities written in TypeScript, providing type-safe alternatives to libraries like Lodash, Ramda, and Just.

Tokens
2.1K
Snippets
15
Records
17
Agent score
68%

What's inside Remeda

  1. Perform optimized data transformations with pipe

    The pipe function allows you to chain Remeda utilities in the order they are computed. It automatically detects functions that can be computed lazily and optimizes the pipeline to defer expensive computations until the results are actually needed.
    import { pipe, map, unique, take } from "remeda";
    
    const DATA = [1, 2, 2, 3, 3, 4, 5, 6];
    
    const result = pipe(
      DATA,
      map((x) => {
        console.log("iterate", x);
        return x;
      }),
      unique(),
      take(3),
    );
    // Result: [1, 2, 3]
    // The map function only iterates until the 'take(3)' condition is met.
  2. Migrate Lodash differenceBy to Remeda

    Remeda does not provide a direct differenceBy equivalent. Recreate this logic using a composition of filter, piped, isNot, isIncludedIn, and map.

    • If the iteratee is a property name, use the prop function.
    • Handle nullish inputs explicitly using ?? [] or isNonNullish checks.
    • If no iteratee is provided, it behaves like difference.
    // Function iteratee
    // Lodash: _.differenceBy(DATA, values, iteratee);
    filter(DATA, piped(iteratee, isNot(isIncludedIn(map(values, iteratee)))));
    
    // Property iteratee
    // Lodash: _.differenceBy(DATA, values, "x");
    filter(DATA, piped(prop("x"), isNot(isIncludedIn(map(values, prop("x"))))));
    
    // Multiple exclusion arrays
    // Lodash: _.differenceBy(DATA, a, b, c, iteratee);
    filter(DATA, piped(iteratee, isNot(isIncludedIn(map([...a, ...b, ...c], iteratee)))));
  3. Handle array extension during migration

    Remeda does not have a direct equivalent for extending arrays via a merge function. For regular arrays, Just's extend behavior is similar to splice. Use Remeda's splice to achieve similar results.
    // Just
    const DATA = [...];
    extend(DATA, b);
    
    // Remeda
    let DATA = [...];
    DATA = splice(DATA, 0 /* start */, b.length /* deleteCount */, b /* replacement */);
  4. Use Remeda functions in data-first and data-last styles

    Remeda functions feature automatic currying, allowing them to be used in two styles:

    1. Data-first: The data is passed as the first argument. This is the standard imperative style and provides the best IDE auto-complete for subsequent arguments.
    2. Data-last: The data argument is omitted, creating a curried version of the function. This style is designed for use within pipe() for functional data transformations.
    import { pick, pipe } from "remeda";
    
    const obj = { firstName: "John", lastName: "Doe", age: 30 };
    
    // Data-first approach
    pick(obj, ["firstName", "lastName"]);
    
    // Data-last approach (used in a pipe)
    pipe(
      obj, 
      pick(["firstName", "lastName"])
    );
  5. Migrate Lodash flatten and flattenDeep to Remeda

    Use Remeda's flat function.

    • For flatten (depth 1), use flat(DATA) or flat(DATA, 1).
    • For flattenDeep, use flat with a high constant integer (e.g., 100). Avoid using Infinity or Number.MAX_INTEGER as they result in inefficient typing.
    // Lodash flatten(DATA) -> Remeda
    flat(DATA);
    
    // Lodash flattenDeep(DATA) -> Remeda
    flat(DATA, 100); // Use a high constant
  6. Migrate Lodash difference to Remeda

    Remeda's difference treats inputs as multisets (respecting item duplication), whereas Lodash removes all matching values.

    Key migration differences:

    1. Duplicates: To remove all copies of matching items (Lodash style), use a composition of filter, isNot, and isIncludedIn.
    2. Arguments: Lodash accepts multiple exclusion arrays as separate arguments; Remeda requires a single array. Use the spread operator to flatten multiple arrays.
    3. Required Parameters: Remeda requires the exclusion array; Lodash allows it to be omitted (returning a shallow clone).
    4. Nullish Inputs: Remeda requires explicit handling of null or undefined inputs (e.g., using nullish coalescing ?? []).
    // Without duplicate values
    // Lodash: _.difference(uniqueData, uniqueValues);
    difference(uniqueData, uniqueValues);
    
    // With duplicate values (Lodash semantics)
    // Lodash: _.difference(dataWithDuplicates, uniqueValues);
    filter(dataWithDuplicates, isNot(isIncludedIn(uniqueValues)));
    
    // Multiple exclusion arrays
    // Lodash: _.difference(DATA, a, b, c);
    difference(DATA, [...a, ...b, ...c]);
    
    // Missing exclusion array
    // Lodash: _.difference(DATA);
    difference(DATA, []); // or [...DATA]
    
    // Nullish inputs
    // Lodash: _.difference(DATA, values);
    difference(DATA ?? [], values);
  7. Migrate Remeda from v1 to v2

    v1

    Remeda v2 introduces breaking changes focused on modernization and simplification, specifically affecting parameter types, return types, and runtime edge-case handling for some functions. To migrate safely, follow these steps:

    1. Update to the latest v1 version of Remeda.
    2. Resolve all deprecation errors in your codebase.
    3. Update to the latest v2 version.
    4. Consult the function-by-function migration documentation to address specific runtime or typing breakages and apply solutions to maintain previous behaviors where necessary.
  8. Migrate Lodash compact to Remeda

    To replicate Lodash's compact behavior in Remeda, use filter with the isTruthy predicate.
    // Lodash
    compact(DATA);
    
    // Remeda
    filter(DATA, isTruthy);
  9. Migrate from Ramda addIndex to Remeda

    Remeda does not provide a direct equivalent to Ramda's addIndex because all Remeda functions that iterate over arrays or objects provide the index as the second argument to the callback by default. You can simply use the standard iteration function (like map) and access the index directly in the callback.
    // Ramda
    addIndex(map)((val, idx) => idx + "-" + val, DATA);
    
    // Remeda
    map(DATA, (val, idx) => idx + "-" + val);
  10. Migrate Lodash intersection to Remeda

    Remeda's intersection respects item duplication (multiset behavior), whereas Lodash always returns a de-duplicated array. To match Lodash's output when duplicates are present, wrap the result in unique().
    // No duplicates
    // Lodash: intersection([2, 1], [2, 3]);
    intersection([2, 1], [2, 3]);
    
    // With duplicates
    // Lodash: intersection([1, 1], [1, 1]);
    unique(intersection([1, 1], [1, 1]));
  11. Merge multiple objects in Remeda

    To merge more than two objects, use mergeAll, which accepts an array of objects. Note that mergeAll performs a shallow merge. If a deep merge of multiple objects is required, you must manually handle the sequence or use mergeDeep iteratively, as there is no direct multi-object deep merge equivalent in Remeda.
    // Just
    const DATA = { ... };
    extend(DATA, b, c, d);
    
    // Remeda (Example using mergeDeep for multiple objects)
    let DATA = { ... };
    DATA = mergeDeep([DATA, b, c, d]);
  12. Migrate Lodash differenceWith to Remeda

    Remeda's differenceWith is similar to Lodash's but with two key differences:

    1. It accepts only a single values array (not a variadic list). Use the spread operator for multiple arrays.
    2. Nullish inputs must be handled explicitly.
    // Single exclusion array
    // Lodash: _.differenceWith(DATA, values, comparator);
    differenceWith(DATA, values, comparator);
    
    // Multiple exclusion arrays
    // Lodash: _.differenceWith(DATA, a, b, c, comparator);
    differenceWith(DATA, [...a, ...b, ...c], comparator);
    
    // Nullish inputs
    differenceWith(DATA ?? [], values, comparator);