Implementieren Sie einen FuzzyFinder

14

Inspiriert von diesem Link, den ich auf Reddit gefunden habe .

Ein FuzzyFinder ist eine Funktion vieler Texteditoren. Wenn Sie mit Sder Eingabe eines Dateipfads beginnen , wird der FuzzyFinder gestartet und zeigt Ihnen alle Dateien im aktuellen Verzeichnis mit der eingegebenen Zeichenfolge, sortiert nach der Position Sin der Datei.

Ihre Aufgabe ist es, einen Fuzzy-Finder zu implementieren. Es sollte sich um ein Programm oder eine Funktion handeln, die (über stdin, ein Funktionsargument oder eine Befehlszeile) eine Zeichenfolge Sund eine Liste von Zeichenfolgen verwendet L, die wie gewünscht formatiert sind und das Ergebnis der Ausführung des Fuzzy-Finders zurückgibt oder ausgibt. Die Suche sollte zwischen Groß- und Kleinschreibung unterscheiden. Ergebnisse, bei denen Ssich mehrere Zeichenfolgen an derselben Position befinden, können nach Belieben sortiert werden.

Beispiel:

Input: mig, [imig, mig, migd, do, Mig]
Output:
    [mig, migd, imig]
OR
    [migd, mig, imig]

Das ist Codegolf, also gewinnt die kürzeste Lösung.

kirbyfan64sos
quelle
Können wir annehmen, dass alle Eingaben in Kleinbuchstaben erfolgen, oder sollten wir die Fuzzy-Übereinstimmung auch für Großbuchstaben verwenden?
Kade
1
@ Vioz- Nein; Bei der Suche muss zwischen Groß- und Kleinschreibung unterschieden werden. Ich habe die Frage und das Beispiel aktualisiert.
kirbyfan64sos

Antworten:

5

Pyth, 9 Bytes

oxNzf}zTQ

Probieren Sie es online aus: Demonstration

Erläuterung:

            implicit: z = input string, Q = input list
    f   Q   filter Q for elements T, which satisfy:
     }zT      z is substring of T
o           order the remaining strings N by:
 xNz          the index of z in N
Jakube
quelle
1
Dies war genau das gleiche Pyth-Programm, das ich während meiner Tests hatte. :)
kirbyfan64sos
5

Python 2, 65

def f(s,l):g=lambda x:x.find(s)+1;print sorted(filter(g,l),key=g)

Der Ausdruck x.find(s)gibt die Position des ersten Auftretens von sin zurück xund ergibt -1keine Übereinstimmung. Wir fügen 1dem Ergebnis hinzu, dass keine Übereinstimmung mit entspricht, 0und lassen uns filtersie heraus. Wir sortieren dann nach der Match-Position, die durch die Verschiebung um 1 nicht beeinflusst wird.

xnor
quelle
5

CJam, 18 15 Bytes

{1$#)}q~2$,@$p;

Probieren Sie es online im CJam-Interpreter aus .

I / O

Eingang:

"mig" ["imig" "mig" "migd" "do" "Mig"]

Ausgabe:

["mig" "migd" "imig"]

Wie es funktioniert

      q~        e# Read and evaluate the input from STDIN.
                e# Pushes a needle and an array of haystacks.
{    }          e# Define a code block:
 1$             e#   Copy the needle.
   #            e#   Compute the index of the needle in the haystack.
    )           e#   Add 1 to the index.
        2$      e# Copy the block.
          ,     e# Filter: Keep only haystacks for which the code block
                e#         pushed a non-zero value.
           @    e# Rotate the block on top of the stack.
            $   e# Sort: Arrange the haystacks according to the values
                e#       pushed by the code block.
             p  e# Print the filtered and sorted haystacks.
              ; e# Discard the needle.
Dennis
quelle
5

GolfScript, 13 Bytes

~{?)}+\1$,\$`

Dies ist eine der seltenen Situationen, in denen GolfScript CJam schlagen kann, indem Blockverkettung verwendet wird und ein paar Freiheiten mit den Eingaben gemacht werden, die nach Belieben formatiert werden können .

Versuchen Sie es online in Web GolfScript .

I / O

Eingang

["imig" "mig" "migd" "do" "Mig"] {"mig"}

Ausgabe

["migd" "mig" "imig"]

Wie es funktioniert

~             # Evaluate the input from STDIN.
              # Pushes an array of haystacks and a needle in a block.
 {?)}         # Push a code block that computes an index and increments it.
     +        # Concatenate that block with the needle block.
      \1$     # Swap the block with the arrays of haystacks and copy the block.
         ,    # Filter: Keep only haystacks for which the code block
              #         pushed a non-zero value.
          \   # Swap the array of haystacks with the code block.
           $  # Sort: Arrange the haystacks according to the values
              #       pushed by the code block.
            ` # Inspect: Format the array for pretty printing.
Dennis
quelle
3

JavaScript ES6, 68 Byte

(s,l,f=j=>j.indexOf(s))=>l.filter(w=>~f(w)).sort((a,b)=>f(a)>f(b))

Dies ist eine anonyme Funktion, die Parameter s(Dateipfadzeichenfolge) und l(Array von Zeichenfolgen) akzeptiert. Das folgende Stack-Snippet enthält unbenutzten Code, der in ES5 konvertiert wurde, sodass mehr Benutzer ihn problemlos testen können. (Wenn Sie Firefox haben, können Sie die schönere Testsuite von edc65 verwenden, die in seiner Antwort zu finden ist.)

f=function(s,l){
  g=function(j){
    return j.search(s)
  }
  
  return l.filter(function(w){
    return ~g(w)
  }).sort(function(a,b){
    return g(a)>g(b)
  })
}

id=document.getElementById;run=function(){document.getElementById('output').innerHTML=f(document.getElementById('s').value,document.getElementById('l').value.split(', ')).join(', ')};document.getElementById('run').onclick=run;run()
<label>File path: <input type="text" id="s" value="mig" /></label><br />
<label>Files: <input type="text" id="l" value="imig, mig, migd, do, Mig" /></label><br />
<button id="run">Run</button><br />
Output: <output id="output"></output>

NinjaBearMonkey
quelle
Beeindruckend! Blöd, dass ich Zeit verliere, eine Testsuite vorzubereiten!
edc65
3

[Gedrückt halten] Pyth, 24 Bytes

JwKcwdVlK=G.)KI}JGaYG))Y

Versuch ist hier

Ich bin ziemlich neu bei Code Golfing / Pyth und bin mir nicht sicher, ob es optimal ist, aber ich arbeite daran!

Update: Ich glaube nicht, dass ich richtig sortiere, und ich kann es nicht zum Laufen bringen. Ich weiß, dass oes sich um eine Sortierung nach der Position von S handelt, also verwende ich .:GlJ, um alle Teilzeichenfolgen der Länge von S für das aktuelle Element Gund anschließend xden Index des ersten Vorkommens von zu finden S, aber ich kann Lambda nicht richtig einstellen.

cmxu
quelle
Check out zund Q. Wenn Sie sie verwenden, erhalten Sie sofort 18 Bytes. Und Sie können die lin VlK=> 17 Bytes ( Link )
entfernen
Übrigens, Ihr Code funktioniert nicht. Probieren Sie den Testfall aus:imig mig migd do Mig imig
Jakube 22.06.15
Ich habe eine funktionierende 9-Byte-Lösung. Wenn Sie Hilfe in Pyth benötigen, treten Sie dem Chat bei.
Jakube
Oh cool! Ich werde versuchen herauszufinden, wie du es heute Abend gemacht hast. Danke für all die Hilfe! (Ich muss noch 1
Rufpunkt
1
@Changming Hat dir den Punkt gegeben. :)
kirbyfan64sos
2

JavaScript ( ES6 ), 68

Das ist fast dasselbe wie bei der @NBM-Antwort (auch wenn sie nicht kopiert wurde), daher erwarte ich keine Gegenstimmen. Trotzdem viel Spaß mit dem Snippet

Eine Funktion mit einem String und einem String-Array-Argument gibt ein String-Array zurück. Filtern und dann sortieren.

Testlaufe das folgende Snippet (nur in EcmaScript 6, Firefox)

f=(s,l,i=t=>t.indexOf(s))=>l.filter(t=>~i(t)).sort((t,u)=>i(t)-i(u))

$(function(){
  $("#S,#L").on("keyup", 
   function() { 
     $('#O').val(f(S.value,L.value.split('\n')).join('\n'))
   } );
  $("#S").trigger('keyup');
})
#S,#L,#O { width: 400px }
#L,#O { height: 100px }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Input String<br><input id=S value='mig'><br>
Input List<br><textarea id=L>
imig
mig
migd
do
Mig
</textarea><br>
Output List<br><textarea id=O readonly></textarea>

edc65
quelle
2

ORACLE, 60

Zählt das?

select * from t where a like '%mig%' order by instr(a,'mig')

MonkeyZeus
quelle
Es könnte zählen, aber es müsste sich um eine Oracle- Prozedur handeln , die die Daten als Argumente verwendet.
kirbyfan64sos
Ob es zählt oder nicht, ich finde es cool. Die erste Code-Golf-Lösung, die ich wirklich verstehe. Gute Arbeit!
Thomas Weller
@ ThomasWeller Danke! Diese Code-Golfer können sicherlich sehr intelligent sein, aber manchmal ist KISS alles, was Sie brauchen!
MonkeyZeus
2

Haskell, 129 116

116 (Dank an Franky):

import Data.List
h s=map snd.sort.map(\x->((head[c|c<-[0..length x],isPrefixOf s(drop c x)]),x)).filter(isInfixOf s)

129

import Data.List
f s n=map snd(sort(map(\x->((head [c|c<-[0..length x],isPrefixOf s(drop c x)]),x))(filter(\x->isInfixOf s x)n)))

Nun, es ist ziemlich lang, vielleicht finde ich heraus, wie ich es ein bisschen verkürzen kann ...

Pfand
quelle
1
Shave Off 13:h s=map snd.sort.map(\x->((head[c|c<-[0..length x],isPrefixOf s(drop c x)]),x)).filter(isInfixOf s)
Franky
2

Python 2, 69 68 66 Bytes

Ich habe soeben eine Funktion erstellt, die sals Zeichenfolge für die Übereinstimmung in einer Liste von Zeichenfolgen dientn

Edit 1: Danke an Jakube fürs Abschlagen eines Bytes.

lambda s,n:sorted([x for x in n if s in x],key=lambda x:x.find(s))

Schau es dir hier an.

Kade
quelle
1

Rubin, 63

p=->(w,l){l.find_all{|x|x[w]}.sort{|a,b|a.index(w)-b.index(w)}}

Lauf

irb(main):022:0> p["mig", ["imig", "mig", "migd", "do", "Mig"]]
=> ["migd", "mig", "imig"]

Anmerkungen

  1. Finden Sie zuerst alle passenden Wörter mit find_all
  2. Sortieren nach Indexposition des gesuchten Wortes.

Bearbeiten (von daneiro)

Rubin, 49

p=->w,l{l.select{|x|x[w]}.sort_by{|e|e.index(w)}}
bsd
quelle
1
Gleiche in 49 Zeichen:p=->w,l{l.select{|x|x[w]}.sort_by{|e|e.index(w)}}
daniero
@daniero Bitte poste es als deine Antwort. Ich werde stimmen!
Bsd
1
Nein, das ist wirklich in Ordnung :) Meine Version ist nur eine Verbesserung von Ihnen. Ich denke, sie sind zu ähnlich, um separate Antworten zu geben. selectist ein Alias ​​für find_all,und sortund sort_by sind im Grunde die gleichen Dinge in leicht unterschiedlichen Umhüllungen. Ich stimme dir stattdessen zu, weil du über die gleiche Lösung nachgedacht hast wie ich;)
denkst
0

Schläger 46 Bytes

(for/list((i l)#:when(string-contains? i s))i)

Verwendung:

(define (f s l)
 (for/list((i l)#:when(string-contains? i s))i))

Testen:

(f "mig" '["imig" "mig" "migd" "do" "Mig"])

Ausgabe:

'("imig" "mig" "migd")
rnso
quelle
0

Groovy, 32 Bytes

{a,b->a.findAll{it.contains(b)}}
Magische Kraken-Urne
quelle
0

Pip , 15 Bytes

14 Byte Code, +1 für -pFlag.

Yq_@?ySKyN_FIg

Übernimmt die Liste als Befehlszeilenargumente und die Zeichenfolge aus stdin. Probieren Sie es online!

Erläuterung

Yq              Yank a line of stdin into y
           FIg  Filter array of cmdline args by this function:
        yN_       Count occurrences of y in arg
      SK        Sort the resulting list using this key function:
  _@?y            Index of y in arg
                Print the Pip representation of the list (implicit, -p flag)
DLosc
quelle