From 1b543ce297006a980899aeed049bba8cd2dbdce8 Mon Sep 17 00:00:00 2001
From: Kenan Yusuf <kenan.m.yusuf@gmail.com>
Date: Tue, 10 Sep 2024 15:41:00 +0100
Subject: [PATCH 1/2] [DataGrid] Refactor string operator filter functions

---
 .../src/colDef/gridStringOperators.ts         | 81 +++++++++----------
 1 file changed, 37 insertions(+), 44 deletions(-)

diff --git a/packages/x-data-grid/src/colDef/gridStringOperators.ts b/packages/x-data-grid/src/colDef/gridStringOperators.ts
index 00c0c0a5b82fb..af0bee1017d77 100644
--- a/packages/x-data-grid/src/colDef/gridStringOperators.ts
+++ b/packages/x-data-grid/src/colDef/gridStringOperators.ts
@@ -20,67 +20,60 @@ export const getGridStringQuickFilterFn: GetApplyQuickFilterFn<any, unknown> = (
   };
 };
 
+const createContainsFilterFn =
+  (disableTrim: boolean, negate: boolean) => (filterItem: GridFilterItem) => {
+    if (!filterItem.value) {
+      return null;
+    }
+    const trimmedValue = disableTrim ? filterItem.value : filterItem.value.trim();
+    const filterRegex = new RegExp(escapeRegExp(trimmedValue), 'i');
+    return (value: any): boolean => {
+      if (value == null) {
+        return negate;
+      }
+      const matches = filterRegex.test(String(value));
+      return negate ? !matches : matches;
+    };
+  };
+
+const createEqualityFilterFn =
+  (disableTrim: boolean, negate: boolean) => (filterItem: GridFilterItem) => {
+    if (!filterItem.value) {
+      return null;
+    }
+    const trimmedValue = disableTrim ? filterItem.value : filterItem.value.trim();
+
+    const collator = new Intl.Collator(undefined, { sensitivity: 'base', usage: 'search' });
+    return (value: any): boolean => {
+      if (value == null) {
+        return negate;
+      }
+      const isEqual = collator.compare(trimmedValue, value.toString()) === 0;
+      return negate ? !isEqual : isEqual;
+    };
+  };
+
 export const getGridStringOperators = (
   disableTrim: boolean = false,
 ): GridFilterOperator<any, number | string | null, any>[] => [
   {
     value: 'contains',
-    getApplyFilterFn: (filterItem: GridFilterItem) => {
-      if (!filterItem.value) {
-        return null;
-      }
-      const filterItemValue = disableTrim ? filterItem.value : filterItem.value.trim();
-
-      const filterRegex = new RegExp(escapeRegExp(filterItemValue), 'i');
-      return (value): boolean => {
-        return value != null ? filterRegex.test(String(value)) : false;
-      };
-    },
+    getApplyFilterFn: createContainsFilterFn(disableTrim, false),
     InputComponent: GridFilterInputValue,
   },
   {
     value: 'doesNotContain',
-    getApplyFilterFn: (filterItem: GridFilterItem) => {
-      if (!filterItem.value) {
-        return null;
-      }
-      const filterItemValue = disableTrim ? filterItem.value : filterItem.value.trim();
-
-      const filterRegex = new RegExp(escapeRegExp(filterItemValue), 'i');
-      return (value): boolean => {
-        return value != null ? !filterRegex.test(String(value)) : true;
-      };
-    },
+    getApplyFilterFn: createContainsFilterFn(disableTrim, true),
     InputComponent: GridFilterInputValue,
   },
   {
     value: 'equals',
-    getApplyFilterFn: (filterItem: GridFilterItem) => {
-      if (!filterItem.value) {
-        return null;
-      }
-      const filterItemValue = disableTrim ? filterItem.value : filterItem.value.trim();
-
-      const collator = new Intl.Collator(undefined, { sensitivity: 'base', usage: 'search' });
-      return (value): boolean => {
-        return value != null ? collator.compare(filterItemValue, value.toString()) === 0 : false;
-      };
-    },
+    getApplyFilterFn: createEqualityFilterFn(disableTrim, false),
     InputComponent: GridFilterInputValue,
   },
   {
     value: 'doesNotEqual',
-    getApplyFilterFn: (filterItem: GridFilterItem) => {
-      if (!filterItem.value) {
-        return null;
-      }
-      const filterItemValue = disableTrim ? filterItem.value : filterItem.value.trim();
-
-      const collator = new Intl.Collator(undefined, { sensitivity: 'base', usage: 'search' });
-      return (value): boolean => {
-        return value != null ? collator.compare(filterItemValue, value.toString()) !== 0 : true;
-      };
-    },
+    getApplyFilterFn: createEqualityFilterFn(disableTrim, true),
     InputComponent: GridFilterInputValue,
   },
   {

From c2bb73c7325e870e34e3d7e16f2660836439fba8 Mon Sep 17 00:00:00 2001
From: Kenan Yusuf <kenan.m.yusuf@gmail.com>
Date: Tue, 10 Sep 2024 15:52:29 +0100
Subject: [PATCH 2/2] empty filter function refactor

---
 .../src/colDef/gridStringOperators.ts         | 19 +++++++++----------
 1 file changed, 9 insertions(+), 10 deletions(-)

diff --git a/packages/x-data-grid/src/colDef/gridStringOperators.ts b/packages/x-data-grid/src/colDef/gridStringOperators.ts
index af0bee1017d77..6b796ba5b4dcc 100644
--- a/packages/x-data-grid/src/colDef/gridStringOperators.ts
+++ b/packages/x-data-grid/src/colDef/gridStringOperators.ts
@@ -53,6 +53,13 @@ const createEqualityFilterFn =
     };
   };
 
+const createEmptyFilterFn = (negate: boolean) => () => {
+  return (value: any): boolean => {
+    const isEmpty = value === '' || value == null;
+    return negate ? !isEmpty : isEmpty;
+  };
+};
+
 export const getGridStringOperators = (
   disableTrim: boolean = false,
 ): GridFilterOperator<any, number | string | null, any>[] => [
@@ -108,20 +115,12 @@ export const getGridStringOperators = (
   },
   {
     value: 'isEmpty',
-    getApplyFilterFn: () => {
-      return (value): boolean => {
-        return value === '' || value == null;
-      };
-    },
+    getApplyFilterFn: createEmptyFilterFn(false),
     requiresFilterValue: false,
   },
   {
     value: 'isNotEmpty',
-    getApplyFilterFn: () => {
-      return (value): boolean => {
-        return value !== '' && value != null;
-      };
-    },
+    getApplyFilterFn: createEmptyFilterFn(true),
     requiresFilterValue: false,
   },
   {