框架
版本
企业版

模糊过滤指南

示例

想直接看实现?可以参考以下示例

API

过滤 API

模糊过滤指南

模糊过滤是一种基于近似匹配来过滤数据的技术。当您想要搜索与给定值相似的数据,而不是精确匹配时,这项技术非常有用。

您可以通过定义一个自定义过滤函数来实现客户端模糊过滤。该函数应接收行、列 ID 和过滤值,并返回一个布尔值,指示该行是否应包含在过滤后的数据中。

模糊过滤主要与全局过滤一起使用,但您也可以将其应用于单个列。我们将讨论这两种情况的模糊过滤实现方法。

注意: 您需要安装 @tanstack/match-sorter-utils 库才能使用模糊过滤。TanStack Match Sorter Utils 是 Kent C. Dodds 的 match-sorter 的一个分支。之所以进行分支,是为了更好地配合 TanStack Table 的逐行过滤方法。

使用 match-sorter 库是可选的,但 TanStack Match Sorter Utils 库提供了一种很好的方式来同时进行模糊过滤和根据其返回的 rank 信息进行排序,这样行就可以根据与搜索查询的匹配程度进行排序。

定义自定义模糊过滤函数

下面是一个自定义模糊过滤函数的示例

typescript
import { rankItem } from '@tanstack/match-sorter-utils';
import { FilterFn } from '@tanstack/table';

const fuzzyFilter: FilterFn<any> = (row, columnId, value, addMeta) => {
  // Rank the item
  const itemRank = rankItem(row.getValue(columnId), value)

  // Store the itemRank info
  addMeta({ itemRank })

  // Return if the item should be filtered in/out
  return itemRank.passed
}
import { rankItem } from '@tanstack/match-sorter-utils';
import { FilterFn } from '@tanstack/table';

const fuzzyFilter: FilterFn<any> = (row, columnId, value, addMeta) => {
  // Rank the item
  const itemRank = rankItem(row.getValue(columnId), value)

  // Store the itemRank info
  addMeta({ itemRank })

  // Return if the item should be filtered in/out
  return itemRank.passed
}

在此函数中,我们使用 @tanstack/match-sorter-utils 库中的 rankItem 函数来对项进行排名。然后,我们将排名信息存储在行的 meta 数据中,并返回该项是否通过了排名标准。

将模糊过滤与全局过滤结合使用

要将模糊过滤与全局过滤结合使用,您可以在 table 实例的 globalFilterFn 选项中指定模糊过滤函数。

typescript
const table = useReactTable({ // or your framework's equivalent function
    columns,
    data,
    filterFns: {
      fuzzy: fuzzyFilter, //define as a filter function that can be used in column definitions
    },
    globalFilterFn: 'fuzzy', //apply fuzzy filter to the global filter (most common use case for fuzzy filter)
    getCoreRowModel: getCoreRowModel(),
    getFilteredRowModel: getFilteredRowModel(), //client side filtering
    getSortedRowModel: getSortedRowModel(), //client side sorting needed if you want to use sorting too.
})
const table = useReactTable({ // or your framework's equivalent function
    columns,
    data,
    filterFns: {
      fuzzy: fuzzyFilter, //define as a filter function that can be used in column definitions
    },
    globalFilterFn: 'fuzzy', //apply fuzzy filter to the global filter (most common use case for fuzzy filter)
    getCoreRowModel: getCoreRowModel(),
    getFilteredRowModel: getFilteredRowModel(), //client side filtering
    getSortedRowModel: getSortedRowModel(), //client side sorting needed if you want to use sorting too.
})

将模糊过滤与列过滤结合使用

要将模糊过滤与列过滤结合使用,您应该首先在 table 实例的 filterFns 选项中定义模糊过滤函数。然后,您可以在列定义的 filterFn 选项中指定模糊过滤函数。

typescript
const column = [
  {
    accessorFn: row => `${row.firstName} ${row.lastName}`,
    id: 'fullName',
    header: 'Full Name',
    cell: info => info.getValue(),
    filterFn: 'fuzzy', //using our custom fuzzy filter function
  },
  // other columns...
];
const column = [
  {
    accessorFn: row => `${row.firstName} ${row.lastName}`,
    id: 'fullName',
    header: 'Full Name',
    cell: info => info.getValue(),
    filterFn: 'fuzzy', //using our custom fuzzy filter function
  },
  // other columns...
];

在此示例中,我们将模糊过滤应用于一个结合了数据中 firstName 和 lastName 字段的列。

模糊过滤排序

当将模糊过滤与列过滤结合使用时,您可能还想根据排名信息对数据进行排序。您可以通过定义一个自定义排序函数来实现此目的。

typescript
import { compareItems } from '@tanstack/match-sorter-utils'
import { sortingFns } from '@tanstack/table'

const fuzzySort: SortingFn<any> = (rowA, rowB, columnId) => {
  let dir = 0

  // Only sort by rank if the column has ranking information
  if (rowA.columnFiltersMeta[columnId]) {
    dir = compareItems(
      rowA.columnFiltersMeta[columnId]?.itemRank!,
      rowB.columnFiltersMeta[columnId]?.itemRank!
    )
  }

  // Provide an alphanumeric fallback for when the item ranks are equal
  return dir === 0 ? sortingFns.alphanumeric(rowA, rowB, columnId) : dir
}
import { compareItems } from '@tanstack/match-sorter-utils'
import { sortingFns } from '@tanstack/table'

const fuzzySort: SortingFn<any> = (rowA, rowB, columnId) => {
  let dir = 0

  // Only sort by rank if the column has ranking information
  if (rowA.columnFiltersMeta[columnId]) {
    dir = compareItems(
      rowA.columnFiltersMeta[columnId]?.itemRank!,
      rowB.columnFiltersMeta[columnId]?.itemRank!
    )
  }

  // Provide an alphanumeric fallback for when the item ranks are equal
  return dir === 0 ? sortingFns.alphanumeric(rowA, rowB, columnId) : dir
}

在此函数中,我们比较两个行的排名信息。如果排名相同,我们则回退到字母数字排序。

然后,您可以在列定义的 sortFn 选项中指定此排序函数。

typescript
{
  accessorFn: row => `${row.firstName} ${row.lastName}`,
  id: 'fullName',
  header: 'Full Name',
  cell: info => info.getValue(),
  filterFn: 'fuzzy', //using our custom fuzzy filter function
  sortFn: 'fuzzySort', //using our custom fuzzy sort function
}
{
  accessorFn: row => `${row.firstName} ${row.lastName}`,
  id: 'fullName',
  header: 'Full Name',
  cell: info => info.getValue(),
  filterFn: 'fuzzy', //using our custom fuzzy filter function
  sortFn: 'fuzzySort', //using our custom fuzzy sort function
}
我们的合作伙伴
Code Rabbit
AG Grid
订阅 Bytes

您的每周 JavaScript 资讯。每周一免费发送给超过 10 万开发者。

Bytes

无垃圾邮件。您可以随时取消订阅。

订阅 Bytes

您的每周 JavaScript 资讯。每周一免费发送给超过 10 万开发者。

Bytes

无垃圾邮件。您可以随时取消订阅。