#3510·ramda

Suggestion: upsert function

Author: AlexFrazerCreated Feb 7, 2025Updated Apr 24, 2025

I've had to write this on almost every project I've been a part of. Essentially, the idea is that you want to create a function which will insert into a list if a predicate isn't matched, or replace in a list if it does exist.

The function signature would be as follows:

  • predicate: the function to determine if the item exists in the list, which will receive item as it iterates
  • mergeStrategy: how to reconcile the existing data with the incoming data (something like mergeLeft, mergeRight, etc)
  • incoming: the value that will be inserted into the list of values
  • data: the list to upsert into

Example implementation:

typescript
type Predicate<T> = (current: T, incoming: T) => boolean;
type MergeStrategy<T, R = T> = (current: T, incoming: T) => R;

const upsert = curry(function upsert(
  predicate: Predicate<T>,
  mergeStrategy: MergeStrategy<T>,
  item: T,
  data: T[]
) {
  const index = findIndex(predicate, data);
  return index < 0
    ? append(item, data)
    : adjust<T>(index, mergeStrategy(item), items)
});