我正在努力让列表理解工作,其目的是验证X
中的每个元素List
后跟X+Incr
(或空列表)。稍后,我将使用该列表并将其与使用lists:seq(From,To,Incr)
生成的列表进行比较。
目的是练习编写测试用例并找到测试属性。
我已完成以下步骤:
1> List.
[1,3,5,8,9,11,13]
2> Incr.
2
3> List2=[X || X <- List, (tl(List) == []) orelse (hd(tl(List)) == X + Incr)].
[1]
对我而言,似乎我的列表理解仅采用List
中的第一个元素,通过过滤器/警卫运行,并停止,但它应该对List
中的EACH元素执行相同操作,对吗?
我希望第3行返回一个列表,看起来像:[1,2,9,11,13]
。
有关如何修改当前理解或完全改变我的方法的任何想法?
PS。我正在使用eqc-quickcheck,通过Quviq's webpage分发,如果这可能会改变解决方法。
答案 0 :(得分:2)
列表理解的问题是List
始终引用整个列表。因此,此条件仅允许那些X
等于List
减去Incr
的第二个元素:
(hd(tl(List)) == X + Incr)
第二个元素总是3,所以这个条件仅适用于X = 1。
列表推导不能“向前看”其他列表元素,所以这可能应该写成递归函数:
check_incr([], _Incr) ->
true;
check_incr([_], _Incr) ->
true;
check_incr([A, B | Rest], Incr) ->
A + Incr == B andalso check_incr([B | Rest], Incr).
答案 1 :(得分:1)
也许我误解了你,但列表理解应该是"creating a list based on existing lists"。这是使用列表推导生成列表而不使用lists:seq
的一种方法:
> Start = 1, Inc = 2, N = 6.
6
> [Start + X*Inc || X <- lists:seq(0,N)].
[1,3,5,7,9,11,13]
答案 2 :(得分:0)
你可以这样做:
> lists:zipwith(fun (X, Y) -> Y - X end, [0 | List], List ++ [0]).
[1,2,2,2,2,2,2,-13]
然后检查所有元素是否等于Incr
,除了第一个应该等于From
,最后一个应该大于或等于-To
。
答案 3 :(得分:0)
一个快速评论是List
值 NOT 在评估理解时发生变化,它总是引用初始列表。它是X
,它遍历列表中的所有元素。这意味着您的测试将始终引用列表的第一个元素。由于列表理解一次为您提供列表元素,因此当您想要比较列表中的元素时,它通常不是一个好的工具。
列表理解无法查看连续的子列表,这是您需要的(如Common Lisp中的MAPLIST)。