Skip to content

Conversation

@ghost
Copy link

@ghost ghost commented Mar 10, 2021

Adds fuzzy search to selectbox using fzy.js. This library performs the fuzzy match itself, and also scores each match so we can display the "best" matches first.

Here's PR preview, I've updated the default script with a convenient example.

@ghost ghost marked this pull request as ready for review March 10, 2021 22:33
@ghost ghost self-requested a review March 10, 2021 22:33
@ghost ghost marked this pull request as draft March 12, 2021 00:30
@ghost ghost marked this pull request as ready for review March 12, 2021 20:06
Copy link
Collaborator

@kmcgrady kmcgrady left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is good. Any test we can add for this?

let arr = _(options)

// keep the options that fuzzy-match our pattern
arr = arr.filter((opt: SelectOption) => fzy.hasMatch(pattern, opt.label))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: can this go in the if (pattern) block below too?

// if the user provided a pattern, sort by score, highest first; otherwise,
// retain original order (scoring based on empty pattern makes no sense)
if (pattern) {
arr = arr.sortBy((opt: SelectOption) => fzy.score(pattern, opt.label))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: No strong opinion on this, but it might be cleaner to just chain the lodash calls without reassigning arr.

Something like

if (!pattern) {
    return options
}

return _(options)
    .filter(...)
    .sortBy(...)
    .reverse()
    .values()

is equivalent and avoids variable reassignment

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had this at first, but the .sortBy() and .reverse() are conditional on pattern, and I don't know how to add a conditional into a chain.

I could chain the sortBy and reverse() together though.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Never mind, saw your comment above about putting the .filter() in the if too. That cleans things up.

@ghost ghost merged commit 8757c14 into streamlit:develop Mar 29, 2021
@ghost ghost deleted the select-fuzzy branch March 29, 2021 22:28
tconkling added a commit that referenced this pull request Mar 30, 2021
* develop:
  Set baseUrl to .
  Speed up CircleCI more (#3025)
  Add events to keep track of theme changes and other theme stats (#3012)
  Have MetricsManager enqueue events when disconnected (#3011)
  Fix for query param issue with base url (#2894)
  Add fuzzy search to selectbox (#2933)
  Informative repr methods for our python classes (#3027)
  ComponentInstance: handle iframe changes (#3015)
tconkling added a commit to tconkling/streamlit that referenced this pull request Mar 30, 2021
* st_form:
  Set baseUrl to .
  Speed up CircleCI more (streamlit#3025)
  Add events to keep track of theme changes and other theme stats (streamlit#3012)
  Have MetricsManager enqueue events when disconnected (streamlit#3011)
  Fix for query param issue with base url (streamlit#2894)
  Add fuzzy search to selectbox (streamlit#2933)
  Informative repr methods for our python classes (streamlit#3027)
  ComponentInstance: handle iframe changes (streamlit#3015)
@hifannie
Copy link

@kmcgrady That's great! Do you know when fuzzy search for multiselect will be merged?

This pull request was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants