@@ -13,6 +13,14 @@ type SearchableData<T> = {
13
13
* If you have multiple fields that should be searchable, simply concat them to the string and return it.
14
14
*/
15
15
toSearchableString : ( data : T ) => string ;
16
+
17
+ /**
18
+ * Gives the possibility to identify data by a unique attribute. Assume you have to search results with the same text they might be valid
19
+ * and represent different data. In this case, you can provide a function that returns a unique identifier for the data.
20
+ * If multiple items with the same identifier are found, only the first one will be returned.
21
+ * This fixes: https://github.com/Expensify/App/issues/53579
22
+ */
23
+ uniqueId ?: ( data : T ) => string | undefined ;
16
24
} ;
17
25
18
26
// There are certain characters appear very often in our search data (email addresses), which we don't need to search for.
@@ -72,6 +80,7 @@ function createFastSearch<T>(dataSets: Array<SearchableData<T>>) {
72
80
const result = tree . findSubstring ( Array . from ( numeric ) ) ;
73
81
74
82
const resultsByDataSet = Array . from ( { length : dataSets . length } , ( ) => new Set < T > ( ) ) ;
83
+ const uniqueMap : Record < number , Record < string , T > > = { } ;
75
84
// eslint-disable-next-line @typescript-eslint/prefer-for-of
76
85
for ( let i = 0 ; i < result . length ; i ++ ) {
77
86
const occurrenceIndex = result [ i ] ;
@@ -85,6 +94,26 @@ function createFastSearch<T>(dataSets: Array<SearchableData<T>>) {
85
94
if ( ! item ) {
86
95
throw new Error ( `[FastSearch] The item with index ${ itemIndexInDataSet } in dataset ${ dataSetIndex } is not defined` ) ;
87
96
}
97
+
98
+ // Check for uniqueness eventually
99
+ const getUniqueId = dataSets [ dataSetIndex ] . uniqueId ;
100
+ if ( getUniqueId ) {
101
+ const uniqueId = getUniqueId ( item ) ;
102
+ if ( ! uniqueId ) {
103
+ // eslint-disable-next-line no-continue
104
+ continue ;
105
+ }
106
+ const hasId = uniqueMap [ dataSetIndex ] ?. [ uniqueId ] ;
107
+ if ( hasId ) {
108
+ // eslint-disable-next-line no-continue
109
+ continue ;
110
+ }
111
+ if ( ! uniqueMap [ dataSetIndex ] ) {
112
+ uniqueMap [ dataSetIndex ] = { } ;
113
+ }
114
+ uniqueMap [ dataSetIndex ] [ uniqueId ] = item ;
115
+ }
116
+
88
117
resultsByDataSet [ dataSetIndex ] . add ( item ) ;
89
118
}
90
119
0 commit comments