Haskell 映射整个数据集以获得结果

Haskell 映射整个数据集以获得结果,haskell,Haskell,假设我有数组: A = "ABACUS" B = "YELLOW" 它们是压缩的:Pairing=zip A B 我还有一个函数Connect::Char->[(Char,Char)]->[(Char,Char,Int)] 我想做的是给一个字符,比如a,找到它在第一个字符串中出现的位置的索引,并返回第二个字符串中相同位置的字符,以及位置,例如,如果我连接了“a”配对,我希望(a,Y,0)和(a,L,2)作为结果 我知道我能行 pos = x!!map fst pairing 检索位置。和

假设我有数组:

A = "ABACUS"

B = "YELLOW"
它们是压缩的:
Pairing=zip A B

我还有一个函数
Connect::Char->[(Char,Char)]->[(Char,Char,Int)]

我想做的是给一个字符,比如a,找到它在第一个字符串中出现的位置的索引,并返回第二个字符串中相同位置的字符,以及位置,例如,如果我连接了“a”配对,我希望(a,Y,0)和(a,L,2)作为结果

我知道我能行

pos = x!!map fst pairing 

检索位置。和
fnd=findIndices(=pos)映射snd配对
以获取第二个字符串中此位置的内容,但在Haskell中,我如何对整个数据集执行此操作(就像使用for循环)以及如何获得输出?

我建议不要将列表压缩在一起,因为这只会增加使用
Data.List
中的
elemIndices
函数的难度。然后,您可以直接使用索引列表从第二个列表中获取值。

我建议不要将列表压缩在一起,因为这会增加使用
Data.list
中的函数
elemIndices
的难度。然后,您可以直接使用索引列表从第二个列表中获取值。

您可以使用另一个
zip
添加索引,然后过滤给定字符并将元组转换为三元组。特别是由于这种重新包装,列表理解似乎是合适的:

connect c pairs = [(a, b, idx) | ((a, b), idx) <- zip pairs [0..], a == c]

connect c pairs=[(a,b,idx)|((a,b,idx)您可以使用另一个
zip
添加索引,然后对给定字符进行筛选并将元组转换为三元组。特别是由于这种重新打包,列表理解似乎是合适的:

connect c pairs = [(a, b, idx) | ((a, b), idx) <- zip pairs [0..], a == c]

connectc pairs=[(a,b,idx)|((a,b,idx)要完全按照您的要求执行(但将函数名的首字母改为小写),我可以定义

connect :: Char -> [(Char,Char)] -> [(Char,Char,Int)]
connect c pairs = [(a,b,n)|((a,b),n) <- zip pairs [0..], a == c]
我们得到

ghci> connect 'A' pairing
[('A','Y',0),('A','L',2)]
然而,我认为使用
zip3
压缩一次而不是两次会更整洁:

connect3 :: Char -> String -> String -> [(Char,Char,Int)]
connect3 c xs ys = filter (\(a,_,_) -> a==c) (zip3 xs ys [0..])
这相当于

connect3' c xs ys = [(a,b,n)| (a,b,n) <- zip3 xs ys [0..], a==c]

在评论中,您说您希望通过另一种方式获得配对

这一次,使用单子
do
表示法最为方便,因为列表是单子的一个示例

connectEither :: (Char,Char) -> String -> String -> [(Char,Char,Int)]
connectEither (c1,c2) xs ys = do
   (a,b,n) <- zip3 xs ys [0..]
   if  a == c1 then return (a,b,n) else
    if b == c2 then return (b,a,n) else 
     fail "Doesn't match - leave it out"
在本例中,它没有包括
('n','a',2)
,因为它只检查一种方式

我们可以通过重用现有函数来实现这两种方式:

connectBoth :: (Char,Char) -> String -> String -> [(Char,Char,Int)]
connectBoth (c1,c2) xs ys = lefts ++ rights where
      lefts  = connect3 c1 xs ys
      rights = connect3 c2 ys xs
这给了我们想要的一切:

ghci> connectBoth ('a','n') "abacus" "banana"
[('a','b',0),('a','n',2),('n','a',2),('n','u',4)]
但不幸的是,事情不止一次:

ghci> connectBoth ('A','A') "Austria" "Antwerp"
[('A','A',0),('A','A',0)]
因此,我们可以使用
Data.List
中的
nub
来消除这种情况(在文件顶部添加
import Data.List

给予

ghci> connectBothOnce ('A','A') "ABACUS" "Antwerp"
[('A','A',0),('A','t',2)]

要完全按照您的要求执行(但将函数名的首字母改为小写),我可以定义

connect :: Char -> [(Char,Char)] -> [(Char,Char,Int)]
connect c pairs = [(a,b,n)|((a,b),n) <- zip pairs [0..], a == c]
我们得到

ghci> connect 'A' pairing
[('A','Y',0),('A','L',2)]
然而,我认为使用
zip3
压缩一次而不是两次会更整洁:

connect3 :: Char -> String -> String -> [(Char,Char,Int)]
connect3 c xs ys = filter (\(a,_,_) -> a==c) (zip3 xs ys [0..])
这相当于

connect3' c xs ys = [(a,b,n)| (a,b,n) <- zip3 xs ys [0..], a==c]

在评论中,您说您希望通过另一种方式获得配对

这一次,使用单子
do
表示法最为方便,因为列表是单子的一个示例

connectEither :: (Char,Char) -> String -> String -> [(Char,Char,Int)]
connectEither (c1,c2) xs ys = do
   (a,b,n) <- zip3 xs ys [0..]
   if  a == c1 then return (a,b,n) else
    if b == c2 then return (b,a,n) else 
     fail "Doesn't match - leave it out"
在本例中,它没有包括
('n','a',2)
,因为它只检查一种方式

我们可以通过重用现有函数来实现这两种方式:

connectBoth :: (Char,Char) -> String -> String -> [(Char,Char,Int)]
connectBoth (c1,c2) xs ys = lefts ++ rights where
      lefts  = connect3 c1 xs ys
      rights = connect3 c2 ys xs
这给了我们想要的一切:

ghci> connectBoth ('a','n') "abacus" "banana"
[('a','b',0),('a','n',2),('n','a',2),('n','u',4)]
但不幸的是,事情不止一次:

ghci> connectBoth ('A','A') "Austria" "Antwerp"
[('A','A',0),('A','A',0)]
因此,我们可以使用
Data.List
中的
nub
来消除这种情况(在文件顶部添加
import Data.List

给予

ghci> connectBothOnce ('A','A') "ABACUS" "Antwerp"
[('A','A',0),('A','t',2)]

以前尝试过用列表理解解决这个问题,但最终在构建代码方面把我自己弄糊涂了!我应该在哪里编写获取索引的代码?以前尝试过用列表理解解决这个问题,但最终在构建代码方面把我自己弄糊涂了!我应该在哪里编写获取索引的代码索引?感谢您花时间向我展示不同的方法。非常感谢!如果我有一个字符元组作为输入(Char,Char),那么[link]connect::(Char,Char)->[(Char,Char)]->[(Char,Char,Int)]我怎么能让它将第二个字符串中的配对也返回到第二个元组呢?即ghci>connect('a',e')“算盘”“黄色”[('A','Y',0),('A','L',2),('E','B',1)?你的意思是
connect('A','E','E')“算盘”“黄色”
应该是
[('A','Y',0),('A','L',2),('B','E',1)]
,因为
E
是第二个字符串?如果是这样,你需要
connect3'(c1,c2)xs ys=(A,B,n,n,n)不,我需要它按我所说的方式返回。我会解释我为什么需要它的上下文,但这会花费太长时间哈!对
连接('A','A')“ABACUS”“ANTWERP”
的答案应该是
[('A','A')]
还是
[('A','A'),('A','A')]
?感谢您花时间向我展示不同的方法。非常感谢!如果我有一个字符元组作为输入(Char,Char),那么[link]connect::(Char,Char)->[(Char,Char)]->[(Char,Char,Int)]我怎么能让它将第二个字符串中的配对也返回到第二个元组?即ghci>connect('a','e')”算盘“黄色”[('A','Y',0),('A','L',2),('E','B',1)?你的意思是
connect('A','E','E')“算盘”黄色”
应该是
[('A','Y',0),('A','L','2),('B','E',1)]
,因为
E
是第二个字符串?如果是这样,你需要
3'(c1,c2)xs ys=(A,B,n,A,n,n)不,我需要它按我所说的方式返回。我会解释我为什么需要它的上下文,但这会花费太长时间哈!对
连接('A','A')“ABACUS”“ANTWERP”
的答案应该是
[('A','A')]
还是
[('A','A'),('A','A')]