하스켈. 두 목록의 INNER JOIN

Nov 08 2020

Google에 요청하고이를 수행하는 데 필요한 도구를 찾으려고 노력했지만 내 문제에 대한 해결책을 찾을 수없는 것 같습니다. 전체 작업은 사전을 사용하여 목록을 번역하고 고유 한 값만 유지하는 것입니다. 예를 들어 다음 입력 :

dict = [("a", "aa"), ("b", "bb")]
list1 = ["a","b","c","a","a","g"]

다음과 같은 출력을 산출해야합니다.

result = ['aa', 'bb']

이것은 내가 지금까지 붙어있는 곳입니다.

main = do
    let dict = [("a", "aa"), ("b", "bb")]
    let list1 = ["a","b","c","g"]
    let keys = map fst dict
    let values = map snd dict
    let result = replace keys values list1
    print(result)

어느 양보

["aa","bb","c","g"]

그래서 내가 사용하는 방법이있을 수 있다는 생각을 해결 filter하거나 map또는 foldl내부 작업을 수행하는 몇 가지 방법으로 다음과 조인

let result = innerJoin values result

현재 다음과 같은 것이 있습니다.

innerJoin :: (Eq a) =>[a] -> [a] -> [a]
innerJoin xs     []     = xs
innerJoin []     ys     = ys
innerJoin (x:xs) (y:ys) = if (elem x (y:ys))
                         then x: innerJoin xs ys
                         else innerJoin xs ys


main = do
    let dict = [("a", "aa"), ("b", "bb")]
    let list1 = ["a","b","c","g"]
    let keys = map fst dict
    let values = map snd dict
    let list2 = innerJoin keys list1
    let result = replace keys values list2
    print(result)

그러나 그것은 ["aa","bb","c","g"]기대하지 않고 반환 됩니다 ["aa","bb"]. 결국 나는 그것을 끝내려고 계획 nub하지만 innerJoin 부분을 파악하는 데 어려움을 겪고 있습니다.

편집하다:

아래 답변 덕분에 문제에 대한 해결책이 있습니다.

innerJoin xs     []     = []
innerJoin []     ys     = []
innerJoin (x:xs) (y:ys) = if (elem x (y:ys))
                         then x: innerJoin xs ys
                         else innerJoin xs ys
catMaybes ls = [x | Just x <- ls]
genList x [] = []
genList [] y = []
genList x (y:ys) = lookup y x: genList x ys
func dict list =  do
    let keys = map fst dict
    let list1 = innerJoin keys list
    catMaybes (genList dict list1)
test1 = func [("a", "aa"),("e", "bb")] ["a","b","c","g","a"]
test2 = func [(1,11),(2,11),(4,44)] [1,2,3,1,2]

답변

3 bradrn Nov 08 2020 at 10:21

이를 위해 원하는 기능은 lookup입니다. 예를 들면 :

lookup "a" [("a", "aa"), ("b", "bb")] = Just "aa"
lookup "b" [("a", "aa"), ("b", "bb")] = Just "bb"
lookup "x" [("a", "aa"), ("b", "bb")] = Nothing   -- "x" is not in the list

여기서 유용한 다른 기능은 Data.Maybe.catMaybes다음과 같습니다. 목록이 [Just 1, Just 2, Nothing, Just 3, Nothing]있고 catMaybes그것에 적용 하면 [1, 2, 3]. 그래서 당신은 결합 할 수 있습니다 lookup및 catMaybes얻기 위해 catMaybes $ map (flip lookup dict) list1원하는 솔루션으로. 추가 개선 사항은 Data.Maybe정의 mapMaybe f xs가와 동등 catMaybe (map f xs)하므로 mapMaybe (flip lookup dict) list1.