← Back to utilities
array

sort-by

Sorts an array of objects by a property or using a custom function. Creates a new sorted array without mutating the original. Can sort by a property name (for objects) or by using a custom iteratee function. Supports ascending and descending order.

Installation

npx fragmen add array/sort-by

Source Code

/**
 * Sorts an array of objects by a property or using a custom function.
 *
 * Creates a new sorted array without mutating the original. Can sort by a property name
 * (for objects) or by using a custom iteratee function. Supports ascending and descending order.
 *
 * @tags pure, array-manipulation
 * @param {T[]} array The array to sort
 * @param {keyof T | ((item: T) => any)} iteratee Property name or function to determine sort order
 * @param {'asc' | 'desc'} order Sort order: 'asc' for ascending (default), 'desc' for descending
 * @returns {T[]} A new sorted array
 *
 * @example
 * ```typescript
 * // Sort by property
 * const users = [
 *   { name: 'Charlie', age: 30 },
 *   { name: 'Alice', age: 25 },
 *   { name: 'Bob', age: 35 }
 * ];
 *
 * const byName = sortBy(users, 'name');
 * console.log(byName);
 * // [{ name: 'Alice', ... }, { name: 'Bob', ... }, { name: 'Charlie', ... }]
 *
 * const byAge = sortBy(users, 'age', 'desc');
 * console.log(byAge);
 * // [{ age: 35, ... }, { age: 30, ... }, { age: 25, ... }]
 *
 * // Sort using function
 * const numbers = [3, 1, 4, 1, 5];
 * const sorted = sortBy(numbers, n => n);
 * console.log(sorted); // [1, 1, 3, 4, 5]
 *
 * // Sort by computed value
 * const words = ['apple', 'pie', 'zoo', 'be'];
 * const byLength = sortBy(words, w => w.length);
 * console.log(byLength); // ['be', 'pie', 'zoo', 'apple']
 * ```
 */
export function sortBy<T>(
  array: T[],
  iteratee: ((item: T) => unknown) | keyof T,
  order: 'asc' | 'desc' = 'asc'
): T[] {
  // Handle edge cases
  if (!Array.isArray(array) || array.length === 0) {
    return [];
  }

  // Create a copy to avoid mutation
  const result = [...array];

  // Determine how to extract the sort value
  const getValue =
    typeof iteratee === 'function'
      ? iteratee
      : (item: T) => {
          if (item !== null && item !== undefined && typeof item === 'object') {
            return (item as Record<string | number | symbol, unknown>)[
              iteratee
            ];
          }
          return item;
        };

  // Sort the array
  result.sort((a, b) => {
    const aValue = getValue(a);
    const bValue = getValue(b);

    // Handle null/undefined
    if (aValue === null || aValue === undefined) {
      if (bValue === null || bValue === undefined) {
        return 0;
      }
      return order === 'asc' ? 1 : -1;
    }
    if (bValue === null || bValue === undefined) {
      return order === 'asc' ? -1 : 1;
    }

    // Compare values
    let comparison = 0;

    if (typeof aValue === 'string' && typeof bValue === 'string') {
      comparison = aValue.localeCompare(bValue);
    } else if (typeof aValue === 'number' && typeof bValue === 'number') {
      comparison = aValue - bValue;
    } else {
      // Fallback to string comparison
      comparison = String(aValue).localeCompare(String(bValue));
    }

    return order === 'asc' ? comparison : -comparison;
  });

  return result;
}

Examples

// Sort by property
const users = [
  { name: 'Charlie', age: 30 },
  { name: 'Alice', age: 25 },
  { name: 'Bob', age: 35 }
];

const byName = sortBy(users, 'name');
console.log(byName);
// [{ name: 'Alice', ... }, { name: 'Bob', ... }, { name: 'Charlie', ... }]

const byAge = sortBy(users, 'age', 'desc');
console.log(byAge);
// [{ age: 35, ... }, { age: 30, ... }, { age: 25, ... }]

// Sort using function
const numbers = [3, 1, 4, 1, 5];
const sorted = sortBy(numbers, n => n);
console.log(sorted); // [1, 1, 3, 4, 5]

// Sort by computed value
const words = ['apple', 'pie', 'zoo', 'be'];
const byLength = sortBy(words, w => w.length);
console.log(byLength); // ['be', 'pie', 'zoo', 'apple']

Related Utilities

chunk

array

Splits an array into chunks of a specified size. Creates a new array containing subarrays (chunks) of the original array, each with a maximum length of the specified size. The last chunk may contain fewer elements if the array length is not evenly divisible by the chunk size.

#pure#array-manipulation

compact

array

Removes falsy values from an array. Creates a new array with all falsy values removed. Falsy values are: false, null, 0, "", undefined, and NaN. This is useful for cleaning arrays and ensuring only truthy values remain.

#pure#array-manipulation

difference

array

Creates an array of values from the first array that are not present in the other arrays. Returns a new array containing elements that exist in the first array but not in any of the subsequent arrays. The order of elements follows the order of the first array. Duplicates in the first array are preserved unless they appear in other arrays.

#pure#array-manipulation

flatten

array

Flattens nested arrays to a specified depth. Creates a new array with all sub-array elements concatenated into it recursively up to the specified depth. A depth of 1 flattens only the first level of nesting, while Infinity flattens all levels.

#pure#array-manipulation

group-by

array

Groups the elements of an array based on the result of a callback function. Creates an object where each key represents a group and the value is an array of items that belong to that group. The grouping is determined by the callback function which is applied to each element.

#pure#array-manipulation

intersection

array

Finds the intersection of two or more arrays. Returns a new array containing only the elements that are present in all provided arrays. The order of elements in the result follows the order of the first array. Duplicates are removed from the result.

#pure#array-manipulation

Quick Actions

Estimated size:2.88 KB

Tags

Parameters

arrayT[]

The array to sort

iterateekeyof T | ((item: T) => any)

Property name or function to determine sort order

order'asc' | 'desc'

Sort order: 'asc' for ascending (default), 'desc' for descending

Returns

T[]

A new sorted array