match-sorter

repository·main·Indexed 13 days ago

https://github.com/kentcdodds/match-sorter

A JavaScript library providing simple, expected, and deterministic best-match sorting of an array. It includes the matchSorter function for basic filtering and sorting, and matchSorterWithRankInfo for accessing internal ranking metadata. Features include configurable search keys with dot-notation for nested properties, customizable match thresholds, diacritic handling, and custom tie-breaking via baseSort.

Tokens
2.2K
Snippets
5
Records
18
Agent score
38%

What's inside match-sorter

  1. Configure search keys with `keys` option

    main

    The keys option allows you to specify which properties of an object should be used for ranking. You can provide an array of strings for top-level keys, or use dot-notation for nested properties.

    • Nested Keys: Use dot-notation (e.g., 'name.first').
    • Arrays in Objects: Use dot-notation with a numeric index (e.g., 'name.0.first') or a * wildcard to match across all elements in an array (e.g., 'aliases.*.name.first').
    • Array of Values: If a key points to an array, the best match from within that array is used for ranking.
    • Property Callbacks: Instead of strings, pass a callback function item => value to resolve the value dynamically. This is useful for complex structures or libraries like Immutable.js.
  2. Configure per-key thresholds, minimum, and maximum rankings

    main

    You can pass an object instead of a string in the keys array to apply specific constraints to a particular key.

    • threshold: Sets the minimum match level required for that specific key.
    • minRanking: A key with a minimum rank will only be promoted if there is at least a simple match.
    • maxRanking: Restricts a key from being promoted beyond a certain rank.
    // Apply a specific threshold to the 'name' key
    matchSorter(list, 'ed', {
      keys: [{threshold: matchSorter.rankings.STARTS_WITH, key: 'name'}, 'color'],
    })
    
    // Restrict 'alias' key to a maximum ranking
    matchSorter(tea, 'A', {
      keys: ['tea', {maxRanking: matchSorter.rankings.STARTS_WITH, key: 'alias'}],
    })
  3. Set match thresholds with `threshold` option

    main

    The threshold option defines the minimum criteria required for a result to be included in the output. The default value is MATCHES.

    Available thresholds (ordered from highest priority to lowest):

    • CASE_SENSITIVE_EQUAL
    • EQUAL
    • STARTS_WITH
    • WORD_STARTS_WITH
    • CONTAINS
    • ACRONYM
    • MATCHES (default)
    • NO_MATCH (returns all items, just sorted by best match)
  4. Customize sorting behavior with `sorter`

    main

    The sorter option allows you to override the core sorting logic.

    • To disable sorting entirely (returning items in their original order but ranked), return the rankedItems as-is.
    • To reverse the order, return a reversed copy of the rankedItems.
  5. Customize tie-breaking with `baseSort`

    main
    The baseSort function is used to tie-break items that have the same ranking. The default behavior uses String.localeCompare for a stable, alphabetic sort. You can provide a custom function (itemA, itemB) => -1 | 0 | 1 to change this.
  6. Use `keys` to search object properties

    main

    When sorting arrays of objects, use the keys option to specify which properties to match against. You can use dot-notation for nested properties or a wildcard * to match elements in an array.

    Supported key types:

    • string: A direct property name or a dot-separated path (e.g., 'user.name').
    • ValueGetterKey: A function (item) => string | string[] to extract values.
    • KeyAttributesOptions: An object to specify key plus custom threshold, minRanking, or maxRanking for that specific key.
  7. Recipe: Match words in non-space separators (snake_case, etc.)

    main

    If your data uses separators other than spaces (like _ in snake_case), use a property callback in the keys option to replace the separator with spaces before matching.

    const list = [
      {name: 'Janice_Kurtis'},
      {name: 'Fred_Mertz'},
    ]
    // Replace underscores with spaces to allow word matching
    matchSorter(list, 'js', {keys: [item => item.name.replace(/_/g, ' ')]})
  8. Use matchSorter for simple best-match sorting

    main

    Use matchSorter to filter and sort an array based on a search string. The function returns a new array containing only the items that match the criteria, sorted by relevance using a sensible ranking algorithm (e.g., case-insensitive equality, starts with, contains, etc.).

    import {matchSorter} from 'match-sorter'
    // or const {matchSorter} = require('match-sorter')
    // or window.matchSorter.matchSorter
    const list = ['hi', 'hey', 'hello', 'sup', 'yo']
    matchSorter(list, 'h') // ['hello', 'hey', 'hi']
    matchSorter(list, 'y') // ['yo', 'hey']
    matchSorter(list, 'z') // []
  9. Recipe: Multi-word fuzzy search across multiple fields

    main
    To match multiple words across different columns (table filtering), split the search string into terms and chain match-sorter calls using reduceRight. This allows a search for "two words" to match rows where "two" is in one column and "words" is in another.
  10. Use matchSorterWithRankInfo to get ranking metadata

    main

    If you need access to the internal ranking metadata computed during the sort (such as the rank value or the index of the item), use matchSorterWithRankInfo. This returns an array of objects containing the original item and its associated ranking information.

    import {matchSorterWithRankInfo} from 'match-sorter'
    
    const list = ['hi', 'hey', 'hello', 'sup', 'yo']
    const rankedResults = matchSorterWithRankInfo(list, 'h')
    // [
    //   {
    //     item: 'hello',
    //     rankedValue: 'hello',
    //     rank: 5,
    //     keyIndex: -1,
    //     keyThreshold: undefined,
    //     index: 2,
    //   },
    //   // ...
    // ]