如何将多级数组中的唯一值映射到 value=>array 的哈希值?

发布于 2024-09-18 06:14:45 字数 362 浏览 5 评论 0原文

我有一个看起来像这样的数组:

[[100, "one"],
 [101, "one"],
 [102, "one"],
 [103, "two"],
 [104, "three"],
 [105, "three"]]

我想做的是创建一个看起来像这样的哈希数组

[{"one" => [100,101,102]},
 {"two" => [103]},
 {"three" => [104,105]}]

数字部分将始终是唯一的,字符串部分将有重复项。我想到这样做的每一种方式都会得到一些长函数,我想知道解决这个问题的“导轨方式”,我确信我缺少一些晦涩的函数。

I have an array that looks something like this:

[[100, "one"],
 [101, "one"],
 [102, "one"],
 [103, "two"],
 [104, "three"],
 [105, "three"]]

What I would like to do is create an array of hashes that looks like this

[{"one" => [100,101,102]},
 {"two" => [103]},
 {"three" => [104,105]}]

The number portion will always be unique, the string portion will have duplicates. Every way I think about doing this I get some long function, I would like to know the "rails way" of going about this, I'm sure there's some obscure function I am missing.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

谁对谁错谁最难过 2024-09-25 06:14:45

不是 Rails 助手,而是常见的 Ruby 习惯用法可以帮助您实现这一目标。一点点

arr.inject({}) { |h,(v,k)| h[k] ||= []; h[k] << v; h }

就可以了。

Not a Rails helper, but a common Ruby idiom can get you there. A little

arr.inject({}) { |h,(v,k)| h[k] ||= []; h[k] << v; h }

will do the trick.

痕至 2024-09-25 06:14:45
array = [[100, "one"], [101, "one"], [102, "one"], [103, "two"], [104, "three"], [105, "three"]]
h = Hash.new { |h,k| h[k] = []}
array.each { |a| h[a[1]] << a[0] }
array = [[100, "one"], [101, "one"], [102, "one"], [103, "two"], [104, "three"], [105, "three"]]
h = Hash.new { |h,k| h[k] = []}
array.each { |a| h[a[1]] << a[0] }
乱了心跳 2024-09-25 06:14:45

如果您需要的只是分组内容,那么您可以使用 Rails group_by 函数:

[[100, "one"],
 [101, "one"],
 [102, "one"], 
 [103, "two"],
 [104, "three"],
 [105, "three"]].group_by { |a| a[1] }

 => #<OrderedHash {"three"=>[[104, "three"], [105, "three"]],
                   "two"=>[[103, "two"]], 
                   "one"=>[[100, "one"], [101, "one"], [102, "one"]]}

与您需要的相差不远。因此,如果您可以按原样使用它,我想那很好,但如果您需要精确的格式,您说的。我认为自己做比使用它和转换更容易。

If what you need is only group stuff then you can use the Rails group_by function :

[[100, "one"],
 [101, "one"],
 [102, "one"], 
 [103, "two"],
 [104, "three"],
 [105, "three"]].group_by { |a| a[1] }

 => #<OrderedHash {"three"=>[[104, "three"], [105, "three"]],
                   "two"=>[[103, "two"]], 
                   "one"=>[[100, "one"], [101, "one"], [102, "one"]]}

Not to far from what you need. So if you can use it as it stand, I guess that's fine, but if you need exaclty the format you said. I think it easier to do it yourself rather than usign this and converting.

小姐丶请自重 2024-09-25 06:14:45

没有真正的功能可以做到这一点。您需要使用注入并创建自己的哈希值。

There are no really function to do that. You need use inject and create yourself you hash.

绝對不後悔。 2024-09-25 06:14:45

正如 shingara 指出的那样,这对于数组的格式来说是非常特定的。您可以像这样做您需要的事情:

a = [...your data...]
r = a.inject( {} ) do |h, el|
  h[el.last] ||= []
  h[el.last] << el.first
  h
end

给出的结果如下: {'one' => [101, 102], ... } 这比您对一键哈希数组的请求更好,IMO。

As shingara points out, this is pretty specific to the format of the array(s). You can do what you need like so:

a = [...your data...]
r = a.inject( {} ) do |h, el|
  h[el.last] ||= []
  h[el.last] << el.first
  h
end

That gives a result like: {'one' => [101, 102], ... } which is better than your request for an array of one-key hashes, IMO.

这是一个实现

your_array.inject(Hash.new{|h,k| h[k] = []}) do |result, (a, b)|
  result[b] << a
  result
end

Here's one implementation

your_array.inject(Hash.new{|h,k| h[k] = []}) do |result, (a, b)|
  result[b] << a
  result
end
伤痕我心 2024-09-25 06:14:45

您需要特定格式(即单元素哈希值数组而不仅仅是沼泽标准哈希值)是否有特定原因?因为在那种情况下,它实际上只是

arr.group_by(&:last)

Is there a specific reason why you need that specific format, i.e. an array of single-element hashes instead of just a bog-standard hash? Because in that case, it would literally be just

arr.group_by(&:last)
雨落□心尘 2024-09-25 06:14:45

我能想到的准确获得您要求的最短方法是:

a = [[100, "one"],
     [101, "one"],
     [102, "one"], 
     [103, "two"],
     [104, "three"],
     [105, "three"]]

b = a.group_by(&:pop)
#=> {"three"=>[[104], [105]], "two"=>[[103]], "one"=>[[100], [101], [102]]}

这可能就是您想要的。

请注意,a 会因此被破坏,

a
#=> [[100], [101], [102], [103], [104], [105]]

如果这让您烦恼,您可以

b = a.map(&:dup).group_by &:pop

改为编写。

如果您确实想要您编写的格式,那么您可以添加另一个地图:

b.map{|h,k| [h => k]}
#=> [{"one" => [100,101,102]}, {"two" => [103]}, {"three" => [104,105]}]

所以总结一下:

[[100, "one"],
 [101, "one"],
 [102, "one"], 
 [103, "two"],
 [104, "three"],
 [105, "three"]].group_by(&:pop).map{ |h,k| [h => k] }

The shortest way to get exactly what you ask for that I can come up with is:

a = [[100, "one"],
     [101, "one"],
     [102, "one"], 
     [103, "two"],
     [104, "three"],
     [105, "three"]]

b = a.group_by(&:pop)
#=> {"three"=>[[104], [105]], "two"=>[[103]], "one"=>[[100], [101], [102]]}

which is probably what you want.

please note that a gets ruined by this

a
#=> [[100], [101], [102], [103], [104], [105]]

if that bothers you, you can write

b = a.map(&:dup).group_by &:pop

instead.

And if you really want that format you wrote then you can add another map:

b.map{|h,k| [h => k]}
#=> [{"one" => [100,101,102]}, {"two" => [103]}, {"three" => [104,105]}]

So to sum up:

[[100, "one"],
 [101, "one"],
 [102, "one"], 
 [103, "two"],
 [104, "three"],
 [105, "three"]].group_by(&:pop).map{ |h,k| [h => k] }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文