本文介绍了在Haskell字符串中交换多对字符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试编写一个Haskell函数,该函数接受一对成对的字母,并将所有成对的字母交换为所有字母的字符串,但是我的想法很尴尬且很单调.

I'm trying to write a Haskell function that takes a string of pairs of letters, and exchanges the letters of the pair in a string of all letters, but what I've come up with feels awkward and unidiomatic.

我有

swap a b = map (\x-> if x == a then b else if x == b then a else x)
sub n = foldr (.) id (zipWith swap (head <$> splitOn "." n) (last <$> splitOn "." n)) ['A'..'Z']

效果很好

> sub "RB.XD.EU.ZM.IJ"
"ARCXUFGHJIKLZNOPQBSTEVWDYM"

> sub "YC.LU.EB.TZ.RB.XD.IJ"
"ARYXBFGHJIKUMNOPQESZLVWDCT"

但是我对Haskell还是陌生的,感觉就像是我的方法—特别是我的swap辅助函数(我只在这里使用)—比需要的要复杂.

but I'm new to Haskell and feel like my approach — especially my swap helper function (which I only use here) — is more elaborate than it needs to be.

是否有更好,更惯用的方法来解决此问题;尤其是利用我错过的语言功能,内置功能或库功能的功能?

Is there a better, more idiomatic, approach to this problem; especially one that takes advantage of a language feature, builtin, or library function that I've missed?

推荐答案

在替换列表上进行左折会使代码更短:

Doing a left fold over the substitution list makes the code shorter:

import Data.List
import Data.List.Split

sub = foldl' swap ['A'..'Z'] . splitOn "." . reverse
  where
    swap az [a,b] = map (\x -> if x == a then b else if x == b then a else x) az

如果您不在意先交换EB还是RB,则放弃相反的操作.

Drop the reverse if you don't care whether EB or RB is swapped first.

如果您要替换而不是交换:

If you'd want to replace instead of a swap:

import Data.List
import Data.List.Split

replace needle replacement haystack =
    intercalate replacement (splitOn needle haystack)

rep = foldl' replace' ['A'..'Z'] . splitOn "."
    where
        replace' az [a,b] = replace [a] [b] az

这篇关于在Haskell字符串中交换多对字符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-27 09:40