Haskell. INNER JOIN di due liste
Ho chiesto a Google e ho cercato di trovare gli strumenti necessari per farlo, ma non riesco a trovare una soluzione al mio problema. L'intero compito è usare un dizionario per tradurre un elenco e mantenere solo i valori univoci. Ad esempio i seguenti input:
dict = [("a", "aa"), ("b", "bb")]
list1 = ["a","b","c","a","a","g"]
dovrebbero produrre il seguente output:
result = ['aa', 'bb']
Questo è qui dove sono rimasto bloccato finora:
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)
che produce
["aa","bb","c","g"]
Quindi, per risolvere questo stavo pensando che ci potrebbe essere un modo per utilizzare filtero mapo foldlin qualche modo di fare un join interno come segue:
let result = innerJoin values result
Attualmente ho qualcosa che assomiglia a questo:
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)
Ma ritorna ["aa","bb","c","g"]e non il previsto ["aa","bb"]. Alla fine ho intenzione di finirlo nub, ma sto lottando per capire la parte innerJoin.
MODIFICARE:
Grazie alla risposta qui sotto ecco la soluzione al problema:
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]
Risposte
La funzione che desideri per questo è lookup. Per esempio:
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
L'altra funzione che è utile qui è Data.Maybe.catMaybes: se hai un elenco di like [Just 1, Just 2, Nothing, Just 3, Nothing]e lo applichi catMaybes, ottieni [1, 2, 3]. Quindi puoi semplicemente combinare lookupe catMaybesottenere catMaybes $ map (flip lookup dict) list1la soluzione desiderata. Un ulteriore perfezionamento è da notare che Data.Maybedefinisce mapMaybe f xscome equivalente a catMaybe (map f xs), quindi puoi semplificarlo fino a mapMaybe (flip lookup dict) list1.