Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Elixir 惯用长生不老药,通过特定的非空键值过滤地图列表?_Elixir - Fatal编程技术网

Elixir 惯用长生不老药,通过特定的非空键值过滤地图列表?

Elixir 惯用长生不老药,通过特定的非空键值过滤地图列表?,elixir,Elixir,我是elixir的新手,我正在试图找出重写此ruby方法的正确方法: def filter_events(events) events.select { |event| event[:id].present? && event[:vhost].present? } end 长生不老药。这就是我到目前为止所做的: def filter_events(events) do Enum.filter(events, &(Map.has_key?(&1, :id)

我是elixir的新手,我正在试图找出重写此ruby方法的正确方法:

def filter_events(events)
  events.select { |event| event[:id].present? && event[:vhost].present? }
end
长生不老药。这就是我到目前为止所做的:

def filter_events(events) do
  Enum.filter(events, &(Map.has_key?(&1, :id) && Map.has_key?(&1, :vhost)))
end

有更好/更惯用的方法吗?

你的例子很短,其实并不重要;它是可读的。但是,大多数示例(包括)都使用内联/匿名函数:

Enum.filter(events, fn(event) ->
  Map.has_key?(event, :vhost) and Map.has_key?(event, :id)
end)
Enum.filter(events, fn(event) -> match?(%{id: _, vhost: _}, event) end)
如果您正在寻找更聪明的东西,可以使用模式匹配

或使用内联函数:

Enum.filter(events, fn(event) ->
  Map.has_key?(event, :vhost) and Map.has_key?(event, :id)
end)
Enum.filter(events, fn(event) -> match?(%{id: _, vhost: _}, event) end)
由于您正在尝试检查键是否存在以及它们的值是否为null,因此以下操作应该有效:

Enum.filter(events, fn(event) ->
  !is_nil(event[:vhost]) and !is_nil(event[:id])
end)

为了多样性,我将把这个答案放在这里。据我所知,最惯用的方法是在过滤函数内部进行模式匹配。它可能看起来更长,但更灵活。当您的地图可能包含所需键的合法
nil
值时(可能不是您的情况,但仍然如此),它允许更好的处理

与您的情况一样,
nil
值无效,应视为无值,可以简化为:

def filter_events(events) do
  Enum.filter(events, fn
    %{id: id, vhost: vhost} when not is_nil(id)
                             and not is_nil(vhost) -> true
    _ -> false
  end)  
end

另一种方法是使用理解:

def filter_events(events) do
  for %{id: id, vhost: vhost} = e when
        not is_nil(id) and
        not is_nil(vhost) <- events, do: e
end

如果您包括ruby方法的实际功能,那就太好了。另外,你能解释一下为什么你不认为这是惯用语吗?我想我是想澄清一下这是不是惯用语,或者是否有更干净的方法来做。我最初考虑使用模式匹配,但我找不到一种方法来匹配映射的值“notnull”。ruby方法获取一个散列数组,然后返回一个数组,该数组只包含那些具有两个键
id
vhost
值的散列。这很好,感谢快速而详细的响应。是否有一种方法可以根据键本身的值进行匹配,以检查它是否存在而不是为零?或者我会做一些类似的事情:
Enum.filter(events,fn(event)->event[:vhost]和event[:id]end)
是的,这样做是合理的,而且读起来很好。太好了,非常感谢您的帮助!作为附带说明,因为它不允许我编辑上述注释,正确的代码实际上是:
Enum.filter(events,fn(event)->!is_nil(event[:vhost])和!is_nil(event[:id])end)
在我的Elixir 1.6.0 dev
Enum.filter(events,&match?({:id,:vhost,},&1))
[%id:42,vhost:42}返回一个空数组。它应该写为:
Enum.filter(事件,&match?({id:},vhost:},&1))
才能工作(它将匹配
%{id:nil,vhost:nil}
这与上一个示例不同。最后一个示例,也是唯一一个执行要求的示例,远远不是惯用的长生不老药。@mudasobwa你说得对,已经晚了。我会再次更新。
def filter_events(events) do
  for e <- events, !is_nil(e[:id]), !is_nil(e[:vhost]), do: e
end
def filter_events(events) do
  for %{id: _, vhost: _} = e <- events, do: e
end