Skip to content

fix(material/table): improve filter predicate efficiency #30172

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 12, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 4 additions & 15 deletions src/material/table/table-data-source.ts
Original file line number Diff line number Diff line change
Expand Up @@ -229,23 +229,12 @@ export class MatTableDataSource<T, P extends MatPaginator = MatPaginator> extend
* @returns Whether the filter matches against the data
*/
filterPredicate: (data: T, filter: string) => boolean = (data: T, filter: string): boolean => {
// Transform the data into a lowercase string of all property values.
const dataStr = Object.keys(data as unknown as Record<string, any>)
.reduce((currentTerm: string, key: string) => {
// Use an obscure Unicode character to delimit the words in the concatenated string.
// This avoids matches where the values of two columns combined will match the user's query
// (e.g. `Flute` and `Stop` will match `Test`). The character is intended to be something
// that has a very low chance of being typed in by somebody in a text field. This one in
// particular is "White up-pointing triangle with dot" from
// https://en.wikipedia.org/wiki/List_of_Unicode_characters
return currentTerm + (data as unknown as Record<string, any>)[key] + '◬';
}, '')
.toLowerCase();

// Transform the filter by converting it to lowercase and removing whitespace.
const transformedFilter = filter.trim().toLowerCase();

return dataStr.indexOf(transformedFilter) != -1;
// Loops over the values in the array and returns true if any of them match the filter string
return Object.values(data as {[key: string]: any}).some(value =>
`${value}`.toLowerCase().includes(transformedFilter),
);
};

constructor(initialData: T[] = []) {
Expand Down
Loading