Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Fuzzy finder as a Go library

ktr
May 18, 2019

Fuzzy finder as a Go library

Go Conference 2019 Spring

ktr

May 18, 2019
Tweet

More Decks by ktr

Other Decks in Programming

Transcript

  1. BU(P$POGFSFODF4QSJOH
    Fuzzy finder as a

    Go library

    View Slide

  2. XIPBNJ
    w LUS Ωλϩʔɺ!LUS@

    w ৽ଔ
    w (Pͱ$-*πʔϧ͕͖͢

    View Slide

  3. View Slide

  4. 'V[[ZpOEFSJTԿ

    View Slide

  5. wೖྗʹର͠ɺ͍͋·͍ݕࡧ

    ʹΑͬͯΠϯλϥΫςΟϒʹ

    ಛఆͷߦΛબ୒Ͱ͖Δ
    wίϚϯυϥΠϯGV[[ZpOEFS

    G[G G[Z FUD

    'V[[ZpOEFS

    View Slide

  6. $ cd `ghq root`/`ghq list | fzf`
    HIR഑ԼͷϦϙδτϦʹҠಈ

    View Slide

  7. $ git branch | egrep -v '^\*' | fzf | 

    xargs git checkout
    ΠϯλϥΫςΟϒʹνΣοΫΞ΢τઌ

    ϒϥϯνΛબ୒

    View Slide

  8. ίϚϯυϥΠϯGV[[ZpOEFSΛ

    ѻ͏ࡍʹൃੜ͢Δ໰୊

    View Slide

  9. w ߦࢦ޲Ͱ͋ΔͨΊɺؚΊΒΕΔ৘ใྔʹ੍ݶ͕͋Δ
    w πʔϧʹ૊ΈࠐΉࡍͷෳࡶ͞
    ίϚϯυϥΠϯGV[[ZpOEFS

    Λѻ͏ࡍʹൃੜ͢Δ໰୊

    View Slide

  10. w ߦࢦ޲Ͱ͋ΔͨΊɺؚΊΒΕΔ৘ใྔʹ੍ݶ͕͋Δ
    w πʔϧʹ૊ΈࠐΉࡍͷෳࡶ͞
    ίϚϯυϥΠϯGV[[ZpOEFS

    Λѻ͏ࡍʹൃੜ͢Δ໰୊

    View Slide

  11. View Slide

  12. View Slide

  13. View Slide

  14. w શ͘ಉ͡಺༰Λද͍ࣔͯ͠Δߦ͕ෳ਺͋Δͱ͖ɺ

    ϓϩάϥϜతɺϢʔβతʹ΋ͦΕΒΛ۠ผͰ͖ͳ͍
    w ৘ใྔΛ૿΍͢͜ͱͰϢχʔΫʹ͸Ͱ͖Δ͕ʜ
    w ͱʹ͔͘ݟͮΒ͍
    w ิॿతͳ৘ใ΋ݕࡧର৅ʹͳΓɺݕࡧਫ਼౓͕௿Լ͢Δ
    ߦࢦ޲ͷݶք

    View Slide

  15. w ߦࢦ޲Ͱ͋ΔͨΊɺؚΊΒΕΔ৘ใྔʹ੍ݶ͕͋Δ
    w πʔϧʹ૊ΈࠐΉࡍͷෳࡶ͞
    ίϚϯυϥΠϯGV[[ZpOEFS

    Λѻ͏ࡍʹൃੜ͢Δ໰୊

    View Slide

  16. w DEίϚϯυͷ֦ு
    w ύεͷཤྺΛΠϯλϥΫςΟϒʹબ୒ͯ͠Ҡಈ
    CCSFOIBODE

    View Slide

  17. w J5VOFTΛίϚϯυϥΠϯ͔Βૢ࡞Ͱ͖Δ
    w J5VOFTͷۂΛΠϯλϥΫςΟϒʹબ୒ɺ࠶ੜ
    LUSJUVOFTDMJ

    View Slide

  18. w ίϚϯυϥΠϯGV[[ZpOEFSͷΠϯετʔϧ
    w πʔϧʹೝࣝͤ͞ΔͨΊͷઃఆ
    w ؀ڥม਺ͳͲ
    πʔϧʹ૊ΈࠐΉࡍͷෳࡶ͞

    View Slide

  19. 'V[[ZpOEFSΛϥΠϒϥϦ

    ͱͯ͠ఏڙ͢Δ

    View Slide

  20. w ߦࢦ޲Ͱ͋ΔͨΊɺؚΊΒΕΔ৘ใྔʹ੍ݶ͕͋Δ
    ‣ ಺෦తʹঢ়ଶΛ࣋ͭ͜ͱ͕Ͱ͖ɺϓϩάϥϜଆͰॏෳߦ
    Λ۠ผͰ͖Δ
    w πʔϧʹ૊ΈࠐΉࡍͷෳࡶ͞
    ‣ (PʹͷΈґଘ͢ΔͨΊɺͦ΋ͦ΋πʔϧͷઃఆ͕ෆཁ
    'V[[ZpOEFSBTBMJCSBSZ

    View Slide

  21. LUSHPGV[[ZpOEFS

    View Slide

  22. func Find(
    slice interface{},
    itemFunc func(i int) string,
    opts ...Option,
    ) (idx int, err error)
    LUSHPGV[[ZpOEFS

    View Slide

  23. EFNP

    View Slide

  24. EFNP
    ίϚϯυϥΠϯGV[[ZpOEFS

    View Slide

  25. func main() {
    var slice []string
    s := bufio.NewScanner(os.Stdin)
    for s.Scan() {
    slice = append(slice, s.Text())
    }
    idx, err := fuzzyfinder.Find(slice, func(i int) string {
    return slice[i]
    })
    if err != nil {
    fmt.Fprintf(os.Stderr, "failed to find: %s\n", err)
    os.Exit(1)
    }
    fmt.Println(slice[idx])
    }

    View Slide

  26. $ (cd $GOPATH/src/github.com/golang/go; git ls-files) | ./cli

    View Slide

  27. EFNP
    ಉҰ಺༰ͷߦͷදࣔ

    View Slide

  28. w ϓϩάϥϜࣗ਎͸ॏෳߦͷ൑ผ͕Ͱ͖Δ͕ɺ

    Ϣʔβ͸౰વ൑ผͰ͖ͳ͍
    w ิॿతͳ৘ใΛϓϨϏϡʔ΢Πϯυ΢Ͱදࣔ
    ಉҰ಺༰ͷߦͷදࣔ

    View Slide

  29. func main() {
    idx, err := fuzzyfinder.FindMulti(songs, func(i int) string {
    return songs[i].Title
    }, fuzzyfinder.WithPreviewWindow(func(i, w, h int) string {
    if i == -1 {
    return ""
    }
    return fmt.Sprintf(
    "Title: %s\nArtist: %s\nAlbum: %s\n",
    songs[i].Title, songs[i].ArtistName, songs[i].AlbumName)
    }))
    if err != nil {
    fmt.Fprintf(os.Stderr, "failed to find: %s\n", err)
    os.Exit(1)
    }
    for _, i := range idx {
    fmt.Println(fmt.Sprintf(
    "%s / %s / %s",
    songs[i].Title, songs[i].ArtistName, songs[i].AlbumName))
    }
    }

    View Slide

  30. $ ./orange

    View Slide

  31. HPGV[[ZpOEFSͷ࣮૷

    View Slide

  32. w ೖྗͱީิߦͷϚονϯά
    w Ϛονͨ͠ߦͷείΞϦϯά
    'V[[ZpOEFSΛߏ੒͢Δཁૉ

    View Slide

  33. w ೖྗlHSQDzΛؚΉߦΛ୳͢
    w ۪௚ʹೋॏϧʔϓճ͚ͩ͢
    Ϛονϯά

    View Slide

  34. w ظ଴͍ͯ͠ΔߦΛ༏ઌతʹදࣔ͢ΔͨΊʹඞཁ
    w ֤ߦΛιʔτ͢ΔͨΊͷείΞΛࢉग़͢Δ
    είΞϦϯά

    View Slide

  35. w ϨʔϕϯγϡλΠϯڑ཭
    w /FFEMFNBO8VOTDI
    w 4NJUI8BUFSNBO
    ৭ʑͳείΞϦϯάΞϧΰϦζϜ

    View Slide

  36. w ϨʔϕϯγϡλΠϯڑ཭εϖϧνΣοΧʔ
    w /FFEMFNBO8VOTDIG[Z
    w 4NJUI8BUFSNBOG[G
    ৭ʑͳείΞϦϯάΞϧΰϦζϜ

    View Slide

  37. w ϨʔϕϯγϡλΠϯڑ཭
    w /FFEMFNBO8VOTDI
    w 4NJUI8BUFSNBO
    ৭ʑͳείΞϦϯάΞϧΰϦζϜ

    View Slide

  38. w άϩʔόϧ
    ΞϥΠϯϝϯτΞϧΰϦζϜͷҰͭ
    w ͋ΔͭͷจࣈྻΛ੔ྻͤ͞ΔͨΊʹ

    ඞཁͳίετΛಈతܭը๏Λ࢖ͬͯٻΊΔ
    /FFEMFNBO8VOTDIΞϧΰϦζϜ

    View Slide

  39. /FFEMFNBO8VOTDIΞϧΰϦζϜ
    | A T A C
    -------------------------
    |
    A|
    C|

    View Slide

  40. w ҎԼͷ͍ͣΕ͔ͷૢ࡞ͷ͏ͪɺ࠷΋είΞ͕ߴ͍΋ͷΛબ୒
    w ۭന Ϊϟοϓ
    ΛࠨͷจࣈྻʹҰͭૠೖ
    w ۭന Ϊϟοϓ
    Λ্ͷจࣈྻʹҰͭૠೖ
    w จࣈͱจࣈͷରԠ෇͚ ϚονPSϛεϚον

    /FFEMFNBO8VOTDIΞϧΰϦζϜ

    View Slide

  41. w ҎԼͷ͍ͣΕ͔ͷૢ࡞ͷ͏ͪɺ࠷΋είΞ͕ߴ͍΋ͷΛબ୒
    w ۭന Ϊϟοϓ
    ΛࠨͷจࣈྻʹҰͭૠೖ
    w ۭന Ϊϟοϓ
    Λ্ͷจࣈྻʹҰͭૠೖ
    w จࣈͱจࣈͷରԠ෇͚ ϚονPSϛεϚον
    PS
    /FFEMFNBO8VOTDIΞϧΰϦζϜ

    View Slide

  42. /FFEMFNBO8VOTDIΞϧΰϦζϜ
    ยํ͕ۭจࣈͷͱ͖ͷ

    είΞ͸࠷ॳʹٻ·Δ
    | A T A C
    -------------------------
    | 0 -2 -4 -6 -8
    A| -2
    C| -4

    View Slide

  43. /FFEMFNBO8VOTDIΞϧΰϦζϜ
    e.g.


    “ATAC” ʹରͯ͠ “” ΛΞϥ
    Πϯϝϯτ͢Δʹ͸ 4 ͭ
    ΪϟοϓΛૠೖ͢Ε͹ྑ͍
    | A T A C
    -------------------------
    | 0 -2 -4 -6 -8
    A| -2
    C| -4

    View Slide

  44. /FFEMFNBO8VOTDIΞϧΰϦζϜ
    “” ͱ “” ʹͦΕͧΕ
    จࣈΛରԠ෇͚Δ৔߹ɺ
    Ϛον͍ͯ͠ΔͷͰ +2

    (0 + 2 = 2)
    | A T A C
    -------------------------
    | 0 -2 -4 -6 -8
    A| -2
    C| -4

    View Slide

  45. /FFEMFNBO8VOTDIΞϧΰϦζϜ
    “A” ͱ “” ͕͋Γɺ

    ޙऀʹΪϟοϓΛૠೖ

    ͢ΔͷͰ -2
    (-2 - 2 = -4)
    | A T A C
    -------------------------
    | 0 -2 -4 -6 -8
    A| -2
    C| -4

    View Slide

  46. /FFEMFNBO8VOTDIΞϧΰϦζϜ
    “” ͱ “A” ͕͋Γɺ

    લऀʹΪϟοϓΛૠೖ

    ͢ΔͷͰ -2

    (-2 - 2 = -4)
    | A T A C
    -------------------------
    | 0 -2 -4 -6 -8
    A| -2
    C| -4

    View Slide

  47. /FFEMFNBO8VOTDIΞϧΰϦζϜ
    match = 2
    left gap = -4
    top gap = -4


    Ͳ͔͜ΒٻΊ͔ͨΛه࿥
    | A T A C
    -------------------------
    | 0 -2 -4 -6 -8
    A| -2 2
    C| -4

    View Slide

  48. /FFEMFNBO8VOTDIΞϧΰϦζϜ
    mismatch = -3
    left gap = 0
    top gap = -6
    | A T A C
    -------------------------
    | 0 -2 -4 -6 -8
    A| -2 2 0
    C| -4

    View Slide

  49. /FFEMFNBO8VOTDIΞϧΰϦζϜ
    match = -2
    left gap = -2
    top gap = -8
    | A T A C
    -------------------------
    | 0 -2 -4 -6 -8
    A| -2 2 0 -2
    C| -4

    View Slide

  50. /FFEMFNBO8VOTDIΞϧΰϦζϜ
    mismatch = -7
    left gap = -4
    top gap = -10
    | A T A C
    -------------------------
    | 0 -2 -4 -6 -8
    A| -2 2 0 -2 -4
    C| -4

    View Slide

  51. | A T A C
    -------------------------
    | 0 -2 -4 -6 -8
    A| -2 2 0 -2 -4
    C| -4 0 1 -1 0
    /FFEMFNBO8VOTDIΞϧΰϦζϜ
    ࠷ऴతͳঢ়ଶ

    View Slide

  52. | A T A C
    -------------------------
    | 0 -2 -4 -6 -8
    A| -2 2 0 -2 -4
    C| -4 0 1 -1 0
    /FFEMFNBO8VOTDIΞϧΰϦζϜ
    ຤ඌͷείΞ͕

    ͜ͷจࣈྻؒͷείΞ

    είΞ = 0

    View Slide

  53. | A T A C
    -------------------------
    | 0 -2 -4 -6 -8
    A| -2 2 0 -2 -4
    C| -4 0 1 -1 0
    /FFEMFNBO8VOTDIΞϧΰϦζϜ
    A T A C
    | |
    A - - C
    ຤ඌ͔Β໼ҹͷॱʹḷΔ

    View Slide

  54. w ϨʔϕϯγϡλΠϯڑ཭
    w /FFEMFNBO8VOTDI
    w 4NJUI8BUFSNBO
    ৭ʑͳείΞϦϯάΞϧΰϦζϜ

    View Slide

  55. w ϩʔΧϧΞϥΠϯϝϯτΞϧΰϦζϜͷҰͭ
    w શମతʹ͸ࣅ͍ͯͳ͍ͭͷจࣈྻͷ

    ہॴతͳΞϥΠϯϝϯτΛٻΊΔΞϧΰϦζϜ
    w /FFEMFNBO8VTDIͱඇৗʹࣅ͍ͯΔ͕ɺ

    είΞ͕ϚΠφεʹͳΒͳ͍
    4NJUI8BUFSNBOΞϧΰϦζϜ

    View Slide

  56. 4NJUI8BUFSNBOΞϧΰϦζϜ
    w ҎԼͷ͍ͣΕ͔ͷૢ࡞ͷ͏ͪɺ࠷΋είΞ͕ߴ͍΋ͷΛબ୒
    w ۭന Ϊϟοϓ
    ΛࠨͷจࣈྻʹҰͭૠೖ
    w ۭന Ϊϟοϓ
    Λ্ͷจࣈྻʹҰͭૠೖ
    w จࣈͱจࣈͷରԠ෇͚ ϚονPSϛεϚον

    w θϩ஋

    View Slide

  57. | A T A C
    -------------------------
    | 0 0 0 0 0
    A| 0 2 0 2 0
    C| 0 0 1 0 4
    4NJUI8BUFSNBOΞϧΰϦζϜ
    ຤ඌ͔Βઌ಄Ͱ͸ͳ͘ɺ
    ෦෼తͳΞϥΠϯϝϯτ
    (຤ඌ͔Β 0 ·Ͱ)

    View Slide

  58. | A T A C
    -------------------------
    | 0 0 0 0 0
    A| 0 2 0 2 0
    C| 0 0 1 0 4
    4NJUI8BUFSNBOΞϧΰϦζϜ
    είΞ = 4

    View Slide

  59. | A T A C
    -------------------------
    | 0 0 0 0 0
    A| 0 2 0 2 0
    C| 0 0 1 0 4
    4NJUI8BUFSNBOΞϧΰϦζϜ
    A T A C
    | |
    - - A C

    View Slide

  60. w ΪϟοϓΛ࡞Δ͜ͱࣗମ΁ͷϖφϧςΟ
    w ઌ಄ҰகϘʔφε
    w FUD
    ϘʔφεͱϖφϧςΟ

    View Slide

  61. w ઃܭ͸ͦΕͧΕͷ࣮૷ʹΑΔ
    w G[ZKIBXUIPSOG[Z"-(03*5).NE
    w G[GKVOFHVOOG[GTSDBMHPBMHPHP
    ϘʔφεͱϖφϧςΟ

    View Slide

  62. ·ͱΊ

    View Slide

  63. ೖྗʹϚον͢ΔߦΛߜΓࠐΉ
    4NJUI8BUFSNBOͰ֤ߦΛείΞϦϯά
    είΞ͕ߴ͍΋ͷ͔Βॱʹදࣔ
    HPGV[[ZpOEFSͷ࣮૷

    View Slide

  64. w ॏෳߦͷ۠ผ
    w ϓϨϏϡʔ΢Πϯυ΢Ͱͷิॿతͳ৘ใͷ෇༩
    w πʔϧ͔ΒGV[[ZpOEFSΛͭ͘Δࡍʹɺ

    ίϚϯυϥΠϯGV[[ZpOEFS΁ͷґଘΛղফͰ
    ͖Δ
    HPGV[[ZpOEFSͷղܾ͢Δ͜ͱ

    View Slide

  65. 5IBOLTGPSMJTUFOJOH

    View Slide