Haskell. İki listenin INNER JOIN

Nov 08 2020

Google'a soruyorum ve bunu yapmak için gerekli araçları bulmaya çalışıyorum, ancak sorunuma bir çözüm bulamıyorum. Tüm görev, bir listeyi çevirmek için bir sözlük kullanmak ve yalnızca benzersiz değerleri korumaktır. Örneğin aşağıdaki girişler:

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

aşağıdaki çıktıyı vermesi gerekiyor:

result = ['aa', 'bb']

Şimdiye kadar burada sıkışıp kaldığım yer burası:

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)

hangi verim

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

Bu yüzden bunu çözmek için aşağıdaki gibi bir iç birleştirmeyi kullanmanın filterveya mapveya bir şekilde yapmanın bir yolu olabileceğini düşünüyordum foldl:

let result = innerJoin values result

Şu anda şuna benzer bir şeyim var:

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)

Ama geri döner ["aa","bb","c","g"]ve beklenen değil ["aa","bb"]. Sonunda bitirmeyi planlıyorum nub, ancak içsel Katılma bölümünü bulmakta zorlanıyorum.

DÜZENLE:

Aşağıdaki cevap sayesinde sorunun çözümü burada:

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]

Yanıtlar

3 bradrn Nov 08 2020 at 10:21

Bunun için istediğiniz işlev lookup. Örneğin:

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

Burada yararlı olan diğer işlev şudur Data.Maybe.catMaybes: Eğer buna benzer [Just 1, Just 2, Nothing, Just 3, Nothing]ve uygulayan bir listeniz catMaybesvarsa, elde edersiniz [1, 2, 3]. Böylece sadece birleştirebilir lookupve istediğiniz çözümü catMaybeselde catMaybes $ map (flip lookup dict) list1edebilirsiniz. Ek bir ayrıntılandırma, bunun eşdeğer olarak Data.Maybetanımlandığına dikkat mapMaybe f xsetmektir catMaybe (map f xs), böylece bunu basitleştirebilirsiniz mapMaybe (flip lookup dict) list1.