FuzzyFinderを実装する


14

Redditで見つけこのリンクに触発されました

FuzzyFinderは、多くのテキストエディターの機能です。ファイルパスを入力し始めるとSと、FuzzyFinderが起動し、入力した文字列を含む現在のディレクトリ内のすべてのファイルを、ファイル内の位置でソートSして表示します。

あなたの仕事はファジーファインダーを実装することです。それは、(stdin、関数引数、またはコマンドラインを介して)文字列Sと文字列のリストを(L必要に応じて)フォーマットし、ファジーファインダーの実行結果を返すか出力するプログラムまたは関数でなければなりません。検索では大文字と小文字を区別する必要があります。S複数の文字列で同じ位置にある結果は、必要に応じて並べ替えることができます。

例:

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

これはコードゴルフであるため、最短のソリューションが優先されます。


すべての入力が小文字であると仮定することはできますか、それとも大文字もあいまい一致する必要がありますか?
ケード

1
@ Vioz-いいえ。検索では大文字と小文字を区別する必要があります。質問と例を更新しました。
kirbyfan64sos

回答:


5

Pyth、9バイト

oxNzf}zTQ

オンラインで試す:デモンストレーション

説明:

            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
これは、テスト中に使用したものとまったく同じPythプログラムでした。:)
kirbyfan64sos

5

Python 2、65

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

この式x.find(s)は、一致しない場合に最初に出現するsin の位置を返します。私たちは、追加の不一致が対応することに結果を私たちにせ、それらを。次に、一致位置でソートしますが、1シフトしても影響を受けません。x-110filter


5

CJam、18 15バイト

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

CJamインタプリタでオンラインで試してください。

I / O

入力:

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

出力:

["mig" "migd" "imig"]

使い方

      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バイト

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

これは、ブロック連結を使用し、希望どおりにフォーマットできる入力にいくつかの自由度を持たせることにより、GolfScriptがCJamを打ち負かすことができるまれな機会の1つです

Web GolfScriptでオンラインで試してください。

I / O

入力

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

出力

["migd" "mig" "imig"]

使い方

~             # 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バイト

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

これは、パラメータs(ファイルパス文字列)およびl(文字列の配列)を受け取る匿名関数です。以下のスタックスニペットには、ES5に変換されたコード化されていないコードが含まれているため、より多くの人が簡単にテストできます。(Firefoxをお持ちの場合は、edc65の回答にあるよりきれいなテストスイートを使用できます。)

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>


うわー!愚かな私はテストスイートの準備に時間を失います!
edc65

3

[保留] Pyth、24バイト

JwKcwdVlK=G.)KI}JGaYG))Y

試してみてください

私はCode Golfing / Pythにかなり慣れていないので、最適かどうかはわかりませんが、取り組んでいます!

更新:私は実際に正しくソートしているとは思わず、それを機能させることができないようです。私はそれoが順序であることを知っており、Sの位置でソートする必要があるので.:GlJ、現在の要素のSの長さのすべての部分文字列を見つけるために使用しG、次にx最初の出現のインデックスを見つけるために使用していますS、しかし、ラムダを正しく設定できないようです。


チェックアウトzQます。それらを使用すると、すぐに18バイトが得られます。また、lin VlK=> 17バイト(リンク)を削除できます
ジャクベ

ところで、あなたのコードは機能しません。テストケースをお試しください:imig mig migd do Mig imig
Jakube

実用的な9バイトのソリューションがあります。Pythでサポートが必要な場合は、チャットに参加してください。
ジャクベ

かっこいい、イケてる!今夜あなたがそれをどうやってやったかを考えてみます。すべての助けてくれてありがとう!(私もチャットすることができます前に、1つの以上の評判ポイントを獲得するつもりの必要性:Pを)
cmxu

1
@Changmingはあなたにポイントを与えました。:)
kirbyfan64sos

2

JavaScript(ES6)、68

これは@NBMの回答とほぼ同じです(たとえコピーされていなくても)、私は賛成票を期待しません。とにかくスニペットをお楽しみください

文字列と文字列配列の引数を持つ関数は、文字列配列を返します。フィルターしてから並べ替えます。

以下のスニペットをテスト実行します(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>


2

オラクル、60

これはカウントされますか?

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


カウントすることもできますが、データを引数として受け取るOracle プロシージャである必要があります。
kirbyfan64sos

数えるかどうかに関係なく、クールだと思います。私が本当に理解した最初のコードゴルフソリューション。すごい仕事!
トーマスウェラー

@ThomasWellerありがとう!これらのコードゴルファーは確かに非常に明るくすることができますが、KISSだけで十分な場合もあります!
MonkeyZeus

2

ハスケル、129 116

116(フランキーのおかげ):

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)))

まあ、それはかなり長いです、多分私はそれを少し短くする方法を見つけるでしょう...


1
13を剃る:h s=map snd.sort.map(\x->((head[c|c<-[0..length x],isPrefixOf s(drop c x)]),x)).filter(isInfixOf s)
フランキー

2

Pythonの2、69 68の 66バイト

s文字列のリストで一致する文字列として受け取る関数を作成しましたn

編集1:バイトをオフにゴルフのためのJakubeに感謝します。

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

こちらをご覧ください。


1

ルビー、63

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

走る

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

ノート

  1. 最初に一致するすべての単語を見つけます find_all
  2. 検索する単語のインデックス位置で並べ替えます。

編集(by daneiro)

ルビー、49

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

1
49文字で同じこと:p=->w,l{l.select{|x|x[w]}.sort_by{|e|e.index(w)}}
daniero

@daniero回答として投稿してください。私は賛成します!
bsd

1
いや、それは本当に大丈夫です:)私のバージョンはあなたの改善です、別々の答えになるにはあまりにも似ていると思います。selectはとのエイリアスでfind_all,ありsortsort_by 基本的にはわずかに異なるラッピングで同じものです。私と同じ解決策を考えて、代わりにあなたに
賛成

0

ラケット46バイト

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

使用法:

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

テスト:

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

出力:

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


0

ピップ、15バイト

14バイトのコード、-pフラグの場合は+1 。

Yq_@?ySKyN_FIg

リストをコマンドライン引数および標準入力からの文字列として取得します。オンラインでお試しください!

説明

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)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.