Реализовать 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 x, отдавая -1без совпадения. Мы добавляем 1к результату, которому соответствует 0несоответствие, выпуская filterих. Затем мы сортируем по позиции совпадения, на которую не влияет смещение на 1.


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, используя конкатенацию блоков и несколько свобод с вводом, который можно отформатировать так, как вы пожелаете .

Попробуйте онлайн в 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

[Hold] Pyth, 24 байта

JwKcwdVlK=G.)KI}JGaYG))Y

Попробуй здесь

Я довольно новичок в Code Golfing / Pyth, поэтому я не уверен, что это оптимально, но я работаю над этим!

Обновление: я не думаю, что я на самом деле сортирую правильно, и я не могу заставить его работать. Я знаю, что oэто по порядку, и мне нужно отсортировать по позиции S, поэтому я использую .:GlJ, чтобы найти все подстроки длины S для текущего элемента, Gа затем x, чтобы найти индекс первого вхождения С, но я не могу правильно установить лямбду.


Проверьте zи Q. Их использование дает вам сразу 18 байтов. И вы можете удалить lin VlK=> 17 байт ( ссылка )
Jakube

Кстати, ваш код не работает. Попробуйте тестовый пример:imig mig migd do Mig imig
Якуб

У меня есть рабочее решение 9 байтов. Если вам нужна помощь в Pyth, присоединяйтесь к чату.
Якуб

О, круто! Я постараюсь выяснить, как ты это сделал сегодня вечером. Спасибо за помощь! (Мне нужно заработать еще 1 очко репутации, прежде чем я
успею

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: Спасибо Якубе за игру в гольф от байта.

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. Сортировать по позиции индекса слова для поиска.

Изменить (от 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 Пожалуйста, опубликуйте это как ваш ответ. Я буду голосовать!
BSD

1
Нет, ничего страшного :) Моя версия - просто твое улучшение, я думаю, что они слишком похожи, чтобы быть отдельными ответами. selectэто псевдоним для find_all,и sortи sort_by в основном это одни и те же вещи в несколько разных упаковках. Вместо этого я возбуждаю вас за то, что вы думаете о том же решении, что и я;)
daniero

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 байтов кода, +1 за -pфлаг.

Yq_@?ySKyN_FIg

Принимает список как аргументы командной строки и строку из stdin. Попробуйте онлайн!

объяснение

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)
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.