在 Erlang 中比较数组元素
我正在尝试学习如何以函数式编程的方式思考,为此,我正在尝试学习 Erlang 并通过codingbat 解决简单的问题。我遇到了比较列表中元素的常见问题。例如,将列表中第 i 个位置元素的值与第 i+1 个位置的值进行比较。所以,我一直在思考和寻找如何在 Erlang (或任何函数式语言)中以函数式方式做到这一点。
请对我温柔点,我在这个函数世界中很新手,但我想学习
提前致谢
I'm trying to learn how to think in a functional programming way, for this, I'm trying to learn Erlang and solving easy problems from codingbat. I came with the common problem of comparing elements inside a list. For example, compare a value of the i-th position element with the value of the i+1-th position of the list. So, I have been thinking and searching how to do this in a functional way in Erlang (or any functional language).
Please, be gentle with me, I'm very newb in this functional world, but I want to learn
Thanks in advance
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
定义一个列表:
定义一个函数f,它接受一个列表
在 Erlang 代码中
Apply 函数
这应该可以工作...还没有编译并运行它,但它应该可以帮助您开始。另外,如果您需要对其进行修改以使其表现不同。
欢迎来到 Erlang ;)
Define a list:
Define a function f, which takes a list
In Erlang code
Apply function
This should work... haven't compiled and run it but it should get you started. Also in case you need to do modifications to it to behave differently.
Welcome to Erlang ;)
我尽量保持温和;-) 因此,函数式方法的主要内容是用术语来思考:什么是输入?应该输出什么?没有什么比单独比较第 i 个元素与第 i+1 个元素更好的了。数据转换必须始终有其目的。甚至 Mazen Harake 的例子也是这样做的。在此示例中,有一个函数仅返回后跟相同值的元素,即过滤给定列表。通常,完成类似的事情有非常不同的方法,这取决于其目的。列表是基本的函数结构,你可以用它做一些令人惊奇的事情,就像 Lisp 向我们展示的那样,但你必须记住它不是数组。
每次您需要重复访问第 i 个元素时,都表明您使用了错误的数据结构。您可以在 Erlang 中构建不同的列表和元组数据结构,这可以更好地满足您的目的。因此,当您遇到将第 i 个元素与第 i+1 个元素进行比较的问题时,您应该停下来思考。其目的是什么?您是否需要像 Mazen Harake 那样执行一些流数据转换,或者您需要随机访问?如果其次你应该使用不同的数据结构(例如数组)。即使这样,您也应该考虑您的任务特征。如果您大部分时间都在阅读而几乎从不写,那么您可以使用
list_to_tuple(L)
,然后使用element/2
进行阅读。当您偶尔需要写入时,您将开始考虑将其分区为多个元组,并且随着写入比率的增加,您最终将得到array
实现。因此,如果您只会执行一次或几次但在简短的列表中,并且您不像我一样是性能狂,那么您可以使用
lists:nth/2
。您可以使用[X1,X2|_] =lists:nthtail(I-1, L)
改进它(L =lists:nthtail(0,L)
的作用如下预期的)。如果您面临更大的列表并且您想多次调用它,您必须重新考虑您的方法。PS:除了列表和树之外,还有许多其他令人着迷的数据结构。以拉链为例。
I try to be gentle ;-) So main thing in functional approach is thinking in terms: What is input? What should be output? There is nothing like comparing the i-th element with the i+1-th element alone. There have to be always purpose of it which will lead to data transformation. Even Mazen Harake's example doing it. In this example there is function which returns only elements which are followed by same value i.e. filters given list. Typically there are very different ways how do similar thing which depends of purpose of it. List is basic functional structure and you can do amazing things with it as Lisp shows us but you have to remember it is not array.
Each time you need access i-th element repeatable it indicates you are using wrong data structure. You can build up different data structures form lists and tuples in Erlang which can serve your purposes better. So when you face problem to compare i-th with i+1-th element you should stop and think. What is purpose of it? Do you need perform some stream data transformation as Mazen Harake does or You need random access? If second you should use different data structure (array for example). Even then you should think about your task characteristics. If you will be mostly read and almost never write then you can use
list_to_tuple(L)
and then read usingelement/2
. When you need write occasionally you will start thinking about partition it to several tuples and as your write ratio will grow you will end up witharray
implementation.So you can use
lists:nth/2
if you will do it only once or several times but on short list and you are not performance freak as I'm. You can improve it using[X1,X2|_] = lists:nthtail(I-1, L)
(L = lists:nthtail(0,L)
works as expected). If you are facing bigger lists and you want call it many times you have to rethink your approach.P.S.: There are many other fascinating data structures except lists and trees. Zippers for example.