Implementa un FuzzyFinder


14

Ispirato da questo link che ho trovato su Reddit .

Un FuzzyFinder è una funzionalità di molti editor di testo. Quando si inizia a digitare un percorso di file S, FuzzyFinder si avvia e mostra tutti i file nella directory corrente contenente la stringa immessa, ordinata in base alla posizione del Sfile.

Il tuo compito è implementare un fuzzy finder. Dovrebbe essere un programma o una funzione che accetta (tramite stdin, argomento della funzione o riga di comando) una stringa Se un elenco di stringhe L, formattate come desiderato, e restituisce o stampa il risultato dell'esecuzione del fuzzy finder. La ricerca dovrebbe essere sensibile al maiuscolo / minuscolo. I risultati che si trovano Snella stessa posizione in più stringhe possono essere ordinati come desiderato.

Esempio:

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

Questo è il golf del codice, quindi vince la soluzione più breve.


Possiamo supporre che tutti gli input siano in minuscolo o dovremmo trovare una corrispondenza fuzzy anche per le maiuscole?
Kade,

1
@ Vioz- No; la ricerca deve essere sensibile al maiuscolo / minuscolo. Ho aggiornato la domanda e l'esempio.
kirbyfan64sos,

Risposte:


5

Pyth, 9 byte

oxNzf}zTQ

Provalo online: dimostrazione

Spiegazione:

            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

1
Questo era esattamente lo stesso programma Pyth che avevo durante i miei test. :)
kirbyfan64sos il

5

Python 2, 65

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

L'espressione x.find(s)restituisce la posizione della prima occorrenza di sin x, dando -1per nessuna corrispondenza. Aggiungiamo 1al risultato a cui non corrisponde alcuna corrispondenza 0, facendoci filteruscire. Ordiniamo quindi in base alla posizione della partita, che non è influenzata dallo spostamento di 1.


5

CJam, 18 15 byte

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

Provalo online nell'interprete CJam .

I / O

Ingresso:

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

Produzione:

["mig" "migd" "imig"]

Come funziona

      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.

5

GolfScript, 13 byte

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

Questa è una di quelle rare occasioni in cui GolfScript può battere CJam, usando la concatenazione a blocchi e prendendo alcune libertà con l'input che può essere formattato come desideri .

Provalo online in Web GolfScript .

I / O

Ingresso

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

Produzione

["migd" "mig" "imig"]

Come funziona

~             # 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.

3

JavaScript ES6, 68 byte

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

Questa è una funzione anonima che accetta parametri s(stringa del percorso del file) e l(matrice di stringhe). Lo snippet di stack seguente contiene codice non convertito convertito in ES5 in modo che più persone possano testarlo facilmente. (Se hai Firefox, puoi usare la suite di test più bella di edc65 trovata nella sua risposta.)

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>


Wow! sciocco che sto perdendo tempo a preparare una suite di test!
edc65,

3

[Hold] Pyth, 24 byte

JwKcwdVlK=G.)KI}JGaYG))Y

Try is here

Sono abbastanza nuovo in Code Golfing / Pyth, quindi non sono sicuro che sia ottimale, ma ci sto lavorando!

Aggiornamento: non penso di essere effettivamente ordinato correttamente e non riesco a farlo funzionare. So che oè ordinato e ho bisogno di ordinare per posizione di S, quindi sto usando .:GlJper trovare tutte le sottostringhe della lunghezza di S per l'elemento corrente Ge quindi xper trovare l'indice della prima occorrenza di S, ma non riesco a impostare lambda correttamente.


Guarda ze Q. Usarli ti dà immediatamente 18 byte. E puoi rimuovere lin VlK=> 17 byte ( link )
Jakube il

A proposito, il tuo codice non funziona. Prova il caso di prova:imig mig migd do Mig imig
Jakube,

Ho una soluzione funzionante di 9 byte. Se vuoi qualche aiuto in Pyth, unisciti alla chat.
Jakube,

Oh, fico! Proverò a capire come hai fatto stasera. Grazie per tutto l'aiuto! (Prima di poter chattare, devo guadagnare 1 punto reputazione in più: P)
cmxu

1
@Changming Ti ho dato il punto. :)
kirbyfan64sos il

2

JavaScript ( ES6 ), 68

È quasi lo stesso della risposta @NBM (anche se non è stata copiata), quindi non mi aspetto voti positivi. Goditi lo snippet comunque

Una funzione con argomenti stringa e array di stringhe, restituisce un array di stringhe. Filtra quindi ordina.

Prova a eseguire lo snippet di seguito (essendo EcmaScript 6, solo 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>


2

ORACLE, 60

Questo conta?

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


Potrebbe contare, ma dovrebbe essere una procedura Oracle che accetta i dati come argomenti.
kirbyfan64sos,

Che conta o no, penso che sia bello. La prima soluzione di golf in codice che abbia mai capito. Ottimo lavoro!
Thomas Weller,

@ThomasWeller Grazie! Questi golfisti di codice possono certamente essere molto brillanti ma a volte KISS è tutto ciò che serve!
MonkeyZeus,

2

Haskell, 129 116

116 (Grazie a 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)))

Beh, è ​​piuttosto lungo, forse scoprirò come accorciarlo un po '...


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

2

Python 2, 69 68 66 byte

Ho appena creato una funzione che accetta scome stringa per corrispondere in un elenco di stringhen

Modifica 1: Grazie a Jakube per il golf di un byte.

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

Controllalo qui.


1

Ruby, 63 anni

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

Correre

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

Appunti

  1. Per prima cosa trova tutte le parole corrispondenti con find_all
  2. Ordina per posizione indice della parola da cercare.

Modifica (di daneiro)

Ruby, 49

p=->w,l{l.select{|x|x[w]}.sort_by{|e|e.index(w)}}

1
Stessa cosa in 49 personaggi:p=->w,l{l.select{|x|x[w]}.sort_by{|e|e.index(w)}}
daniero,

@daniero Per favore pubblicalo come risposta. Valuterò!
bsd

1
No, va bene davvero :) La mia versione è solo un miglioramento della tua, penso che siano troppo simili per essere risposte separate. selectè un alias per find_all,e sorte sort_by sono fondamentalmente le stesse cose in leggermente diverse confezioni. Ti voterò invece, per aver pensato alla mia stessa soluzione;)
daniero,

0

Racchetta 46 byte

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

Uso:

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

test:

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

Produzione:

'("imig" "mig" "migd")


0

seme , 15 byte

14 byte di codice, +1 per la -pbandiera.

Yq_@?ySKyN_FIg

Prende l'elenco come argomenti della riga di comando e la stringa da stdin. Provalo online!

Spiegazione

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)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.