我遇到一个问题,即我有一个数据库,其中包含与歌曲,艺术家和销售人物的存储有关的元组列表。我必须使用songName和artistName在列表中进行迭代,如果它们在数据库中,则必须将销售值加1,并将其与数据库中的其他元组一起输出。如果songName和artistName不在数据库中,则我必须输出数据库中的元组以及包含输入的songName,artistName和first sale的新元组,例如。[("Heartbeat","Kelly Clarkson",7), ("Rise","The Shadows",15), ("Hello", "Adele", 1)]
我对这个问题的解决方案如下:
testData :: [Sales]
testData = [ ("No Lie", "Sean Paul feat. Dua Lipa", 100)
, ("Yes Lie", "Sean Paul feat. Dua Lipa", 10)
, ("Fear & Delight", "The Correspondents", 120) ]
recordSale :: [Sales] -> String -> String-> [Sales]
recordSale [dataSet] trackName artistName = [(trackName, artistName, 1)]
recordSale ((track, artist, qty): xs) trackName artistName
| track == trackName && artist == artistName = xs ++ [(track, artist, qty + 1)]
| otherwise = recordSale xs trackName artistName
| track /= trackName && artist /= artistName = xs ++ [(track, artist, 1)]
我写了一个带有警卫的递归函数,试图在数据集中找到songName和artistName,但是我有一个奇怪的意外输出。
输入数据时,我的输出很奇怪。如果我要输入recordSale testData "Yes Lie" "Sean Paul feat. Dua Lipa"
,程序将输出[("Fear & Delight","The Correspondents",120),("Yes Lie","Sean Paul feat. Dua Lipa",11)]
。接受问题1中描述的预期的缺少元素问题,这是可以预期的。
但是,如果我要进入recordSale testData "Fear & Delight" "The Correspondents"
,我将得到异常的行为或被返回[("Fear & Delight","The Correspondents",1)]
。鉴于这首歌在数据库中,我希望销售数字能增加1。
鉴于只输出了歌曲,而不是附加到列表中的歌曲,我认为这可能是由我的基本情况引起的,recordSale [dataSet] trackName artistName = [(trackName, artistName, 1)]
但我对此不十分确定
我如何返回未包含销售1的列表中的歌曲,以及当成功查询返回到数据库中时将其返回1来停止成功查询吗?
编辑:
替换为recordSale [dataSet] trackName artistName = []
,recordSale [dataSet] trackName artistName = [(trackName, artistName, 1)]
以更准确地反映我在问题2中遇到的问题。
编辑2:编辑问题2的措词,使其更“易读”。
编辑3:减少为一个问题。
您的代码有两个问题。首先是守卫
| otherwise = recordSale xs trackName artistName
| track /= trackName && artist /= artistName = xs ++ [(track, artist, 1)]
什么情况是,当对trackName
与artistName
不完全匹配,该列表将被截断,因为你只传递xs
。处理模式完全不匹配的第二行将永远不会被击中,因为模式是有序的并且otherwise
是万能的。(无论如何,实现都是错误的,因为只要当前元素不匹配,它都会附加一个新元素)
另一个问题是模式
recordSale [dataSet] trackName artistName = [(trackName, artistName, 1)]
当列表仅包含一个元素时,这将匹配,但是如果该元素是匹配项,该怎么办?目前,此情况已被忽略,计数仅设置为1。
因此,我提出以下建议:
(我还用列表++
构造替换了列表串联,:
因为它节省了一些键入操作,并消除了一些混乱情况)
type Sales = (String, String, Int)
testData :: [Sales]
testData = [ ("No Lie", "Sean Paul feat. Dua Lipa", 100)
, ("Yes Lie", "Sean Paul feat. Dua Lipa", 10)
, ("Fear & Delight", "The Correspondents", 120) ]
recordSale :: [Sales] -> String -> String-> [Sales]
recordSale [] trackName artistName = [(trackName, artistName, 1)]
recordSale ((track, artist, qty): xs) trackName artistName
| track == trackName && artist == artistName = (track, artist, qty + 1) : xs
| otherwise = (track, artist, qty) : recordSale xs trackName artistName
在该otherwise
子句中,我不会丢弃当前元素,而是使用递归的其余部分构造一个列表。另一个重要的变化是基本情况。我不匹配一个元素的列表,而是匹配空列表并返回插入了新项目的列表。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句