当n = 0时,对于Elixir的理解

时间:2016-12-09 21:51:03

标签: elixir

我想在Elixir中使用for comprehension循环n次并每次累积一些结果。

一个例子:

<div style="position:relative;">
   <img  style="width:200px;height:200px;" src='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4AwJCBoDRV/pcAAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAABkklEQVRo3u1aQRKDMAgsTI4+xP+/xod4p6fOdNqoARZInXpsY8jCAhsTEpHHHR5+3OS5DZB29ifttKENyiJrBBA6ypEIEJHAyqlFO20Ip7VZON4Do4kWZ3PZC06dI55Je07w0ufKsUNAvCCQxeRo/ksgIwY9NLQA6tlrlSB671sjZe4jEcXAQ2GubIYem5/j+RdB9JopZxuPyEPaafvKEe0CrbliAXD2DlfQCN1DhoGgKhSisR79zt6JRxaniYIsslocx9GejpA3vXGM4qiX+176ckQya9RByA4Rpa1GooOWOGylwmwfIDh7MVE7T/YY1i4qsh+5k12zOIQ+O5oDUrWywEyltaw952p8eGdHABoZ0zIXfjafR8vJImuLBiGLrBbg2obKkbx+GRuRIlppo6YW6ruTJzrQ/QiqFGsio6Li+54d6f3MSH9FJFNyoG2li8YoW2UnVpo9vEn9ao4FPB0d7ZiG9iyyKqnEaPWpLqwKok+sqooHae+izHqJgCuMhmx/UbeDMlVBKJDq53/NabbnCakwWb7DRriDAAAAAElFTkSuQmCC'>
   <table style="width:300px;height:200px;position:absolute;top:0;left:0;" border=1><tr><td>item1</td><td>item2</td></tr></table>
</div>

当n为0时,这将循环1次。当n为0时,我尝试了几种其他方法来获取空列表,但是如果不使用详细构造就无法看到如何做到这一点,这会破坏整个目的理解。我意识到这是因为范围是包容性的。但我想必须有一种方法来获得独占范围,或者其他一些方法来实现空洞的理解,同时仍然具有可读性。我无法找到它。

我想知道在Elixir中使用这种理解是否合理。如果我必须在理解中做出长篇大论,或者制作自己的帮助函数,我就会坚持使用其他方法。

2 个答案:

答案 0 :(得分:3)

0..n是一个包容性范围。从数学上讲,您有[0, n],并且需要[0, n)

在我看来,至少有两种方法可以接近你打算做的事情。

第一个是定义一个实现独占范围的函数,如:

defmodule Util do
  def range(from..to), do: range(from, to)

  def range(n, n), do: []
  def range(from, to) when to < 0, do: from..(to + 1) |> Enum.to_list()
  def range(from, to) when to >= 0, do: from..(to - 1) |> Enum.to_list()
end

此函数始终返回一个列表,而不是范围,只是为了保持一致性:

import Util
for _ <- range(0..n), y <- 1..3, do: y

或者

import Util
for _ <- range(0, n), y <- 1..3, do: y

另一个解决方案是避免理解:

1..3 |> List.duplicate(n) |> Enum.flat_map(&(&1))

我希望这会有所帮助。

答案 1 :(得分:2)

您的理解不会返回空列表的原因是因为范围0..0不为空。如果你运行0..0 |> Enum.map(fn x -> x end),这很明显;你会回来[0]x..y语法是&#34的缩写;为我提供setx开头并以y&#34;结尾的数字;不出所料,从零开始并以零结尾的所有整数的列表包含一个数字 - 零 - 因此应该0..0

换句话说,0..n(转换为List时)的长度始终为n + 1。因此,对该列表的理解也是如此。

如果要排除Enumerable中的第一项,可以使用Enum.drop/2。因此,为了执行第二次理解n次而不是n + 1次(我认为这是基于您所写的内容的目标),以下应该做的伎俩(假设{{ 1}}当然是定义的:

n