Elixir 惯用长生不老药,通过特定的非空键值过滤地图列表?
我是elixir的新手,我正在试图找出重写此ruby方法的正确方法: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)
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 devEnum.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