二郎列表理解,再一次

时间:2014-02-21 13:58:01

标签: erlang list-comprehension

我正在努力让列表理解工作,其目的是验证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分发,如果这可能会改变解决方法。

4 个答案:

答案 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)。