-
-
Notifications
You must be signed in to change notification settings - Fork 4.1k
Search improvements #572
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
Search improvements #572
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -85,7 +85,7 @@ export default { | |
|
||
theStore () { | ||
return this.$store | ||
}, | ||
} | ||
}, | ||
|
||
mounted () { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -58,6 +58,21 @@ export const SPECIAL_TOKENS = { | |
'NaN': NAN | ||
} | ||
|
||
export function specialTokenToString (value) { | ||
if (value === null) { | ||
return 'null' | ||
} else if (value === UNDEFINED) { | ||
return 'undefined' | ||
} else if (value === NAN) { | ||
return 'NaN' | ||
} else if (value === INFINITY) { | ||
return 'Infinity' | ||
} else if (value === NEGATIVE_INFINITY) { | ||
return '-Infinity' | ||
} | ||
return false | ||
} | ||
|
||
/** | ||
* Needed to prevent stack overflow | ||
* while replacing complex objects | ||
|
@@ -312,44 +327,70 @@ function isPrimitive (data) { | |
} | ||
|
||
export function searchDeepInObject (obj, searchTerm) { | ||
var match = false | ||
return internalSearchObject(obj, searchTerm.toLowerCase(), new Map(), 0) | ||
} | ||
|
||
function internalSearchObject (obj, searchTerm, seen, depth) { | ||
let match = false | ||
const keys = Object.keys(obj) | ||
let key, value | ||
for (let i = 0; i < keys.length; i++) { | ||
const key = keys[i] | ||
const value = obj[key] | ||
if (compare(key, searchTerm) || compare(value, searchTerm)) { | ||
match = true | ||
key = keys[i] | ||
value = obj[key] | ||
match = interalSearchCheck(searchTerm, key, value, seen, depth + 1) | ||
if (match) { | ||
break | ||
} | ||
if (isPlainObject(value)) { | ||
match = searchDeepInObject(value, searchTerm) | ||
if (match) { | ||
break | ||
} | ||
} | ||
return match | ||
} | ||
|
||
function internalSearchArray (array, searchTerm, seen, depth) { | ||
let match = false | ||
let value | ||
for (let i = 0; i < array.length; i++) { | ||
value = array[i] | ||
match = interalSearchCheck(searchTerm, null, value, seen, depth + 1) | ||
if (match) { | ||
break | ||
} | ||
} | ||
return match | ||
} | ||
|
||
function compare (mixedValue, stringValue) { | ||
if (Array.isArray(mixedValue) && searchInArray(mixedValue, stringValue.toLowerCase())) { | ||
return true | ||
function interalSearchCheck (searchTerm, key, value, seen, depth) { | ||
if (depth > 10) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's okay for a hotfix, but wouldn't it be better to use something like There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's what the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. oh lol sorry, I thought we couldn't use objects as keys in js maps, not sure why. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For performance reasons, I though it would be nice to have some kind of limit. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
It's the other way around, we can use objects in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've used WeakMap with objects before 😆 About the depth, I don't get what you mean with performance, if we drop the search because we found an object we already found while looking recursively into anothe object, wouldn't that be the sortest way to stop the search? // given
{ a: { b: obj }, c: obj} once we try to lookup // given
var a = {}
var b = { b: { a }}
a.b = b we would only dive till There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Okay, I don't why I had errors with There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, okay so it was to limit deep nested objects no matter repetition. |
||
return false | ||
} | ||
if (('' + mixedValue).toLowerCase().indexOf(stringValue.toLowerCase()) !== -1) { | ||
return true | ||
let match = false | ||
let result | ||
if (key === '_custom') { | ||
key = value.display | ||
value = value.value | ||
} | ||
return false | ||
(result = specialTokenToString(value)) && (value = result) | ||
if (key && compare(key, searchTerm)) { | ||
match = true | ||
seen.set(value, true) | ||
} else if (seen.has(value)) { | ||
match = seen.get(value) | ||
} else if (Array.isArray(value)) { | ||
seen.set(value, null) | ||
match = internalSearchArray(value, searchTerm, seen) | ||
seen.set(value, match) | ||
} else if (isPlainObject(value)) { | ||
seen.set(value, null) | ||
match = internalSearchObject(value, searchTerm, seen) | ||
seen.set(value, match) | ||
} else if (compare(value, searchTerm)) { | ||
match = true | ||
seen.set(value, true) | ||
} | ||
return match | ||
} | ||
|
||
function searchInArray (arr, searchTerm) { | ||
let found = false | ||
for (let i = 0; i < arr.length; i++) { | ||
if (('' + arr[i]).toLowerCase().indexOf(searchTerm) !== -1) { | ||
found = true | ||
break | ||
} | ||
} | ||
return found | ||
function compare (value, stringValue) { | ||
return ('' + value).toLowerCase().indexOf(stringValue) !== -1 | ||
} | ||
|
||
export function sortByKey (state) { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be safer to clear the map when leaving the function to avoid holding references to objects and creating a leak