ruby - 使用不同元素时 ruby​​ 中的 flat_map

标签 ruby

我认为当你有一个可变长度的散列数组并且你想单独处理每个散列时,flat_map 很棒:

data = [
  {'apple' => 'fruit'},
  {'carrot' => 'vegetable'},
  {'orange' => 'fruit', 'pear' => 'fruit'},
  {'lettuce' => 'vegetable'}
] 

data.flat_map(&:to_a).reduce([]) {|acc, (k,v)| acc << Hash[k,v] }
 => [{"apple"=>"fruit"}, {"carrot"=>"vegetable"}, {"orange"=>"fruit"}, {"pear"=>"fruit"}, {"lettuce"=>"vegetable"}] 

但我不认为我完全理解 flat_map。根据docs :

Returns a new array with the concatenated results of running block once for every element in enum.

但是看看这个例子:

[[1], {a: "a"}, {b: "b"}].flat_map(&:to_a)
=> [1, [:a, "a"], [:b, "b"]] 

第一项从内部数组中剥离,其他项转换为数组。它怎么知道要这样做?

当我这样调用 to_a 时:

[1].to_a
 => [1] 
[1].to_a.flatten
 => [1] 

您看到的结果与 flat_map 不同。第一个示例中的 flat_map 正在做什么来剥离数组的项目?

最佳答案

对于任何包含m+n个元素的数组arr,如果

arr.map { ... }

返回

[a1, a2,.., am, o1, o2,.., on]

其中 a1, a2,.., am 是数组,o1, o2,.., on 是数组以外的对象,然后通过更改 map flat_map,保持 block 不变,flat_map 将返回

[*a1, *a2,.., *am, o1, o2,.., on]

示例 1

为了

arr = [[1], {a: "a"}, {b: "b"}]

我们有

arr.map(&:to_a)
  #=> [[1], [[:a, "a"]], [[:b, "b"]]]

因此

arr.flat_map(&:to_a)

会回来

[*[1], *[[:a, "a"]], *[[:b, "b"]]]
  #=> [1, [:a, "a"], [:b, "b"]] 

确实如此。

示例 2

假设现在我们有

arr = [1, 'cat', [2,3], {a: 4}]

然后

arr.map(&:itself)
  #=> [1, "cat", [2, 3], {:a=>4}]

所以

arr.flat_map(&:itself)

被发现返回

[1, "cat", 2, 3, {:a=>4}]

这是减少

[1, "cat", *[2, 3], {:a=>4}]

关于ruby - 使用不同元素时 ruby​​ 中的 flat_map,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40371047/

相关文章:

ruby - 有没有办法重构这段代码?

ruby-on-rails - Bundler::GemNotFound:在使用 Docker 的 Rails 项目的任何源中找不到 mimemagic-0.3.5

javascript - 为什么 EventMachine 比 Node 慢那么多?

ruby-on-rails - Capistrano 在部署时要求输入密码,尽管有 SSH key

ruby - YouTube视频ID正则表达式(RegEx)

ruby - 这是静默忽略 Ruby 异常的最短方法

ruby-on-rails - Rails 3、HTTP 扩展(WebDAV)和 Rack App 安装

ruby - 无法将 ruby​​-debug19 与 1.9.3-p0 一起使用?

ruby - 在不使用 sort 方法的情况下按字母顺序对数组进行排序

ruby-on-rails - ruby rails : How to group list of names based on the initial?