हास्केल। दो सूचियों का 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 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