简体   繁体   English

"Ruby 'group_by'-like 哈希方法"

[英]Ruby 'group_by'-like method for hash

I need a Ruby function that takes a hash as input (keys are Symbols and values are Arrays of Numerics) and returns the list of keys whose associated Arrays have the same first value.我需要一个 Ruby 函数,它以哈希作为输入(键是符号,值是数字数组)并返回其关联数组具有相同第一个值的键列表。

Here is an example :这是一个例子:

h={
  :k1 => [2,3,5,12],
  :k2 => [9,5,6,10],
  :k3 => [2,4,5, 8],
}

f(h) # should return [[:k1,:k3]] 

...because 2 appears as the same value in the two arrays associated with :k1 and :k3 . ...因为 2 在与:k1:k3关联的两个数组中显示为相同的值。 The return Object is an array of array (because, several groups of keys can have the same array first values).返回的 Object 是一个数组数组(因为,几组键可以具有相同的数组第一个值)。

So far, I just grouped the arrays themselves :到目前为止,我只是将数组本身分组:

def f(h)
  h.values.group_by{|ary| ary.first}
end   

# returns {2=>[[2, 3, 5, 12], [2, 4, 5, 8]], 9=>[[9, 5, 6, 10]]}

Why not just use group_by as the title of your question suggests: 为什么不只使用group_by作为问题的标题提示:

h2 = h.group_by { |k, v| v.first }

This gives you something like this: 这给你这样的东西:

{2=>[[:k1, [2, 3, 5, 12]], [:k3, [2, 4, 5, 8]]], 9=>[[:k2, [9, 5, 6, 10]]]}

You can then use this for further processing. 然后,您可以将其用于进一步处理。 Just want the keys? 只想要钥匙?

h3 = h2.values.map { |v| v.map(&:first) }

Only want those with more than one key? 只想拥有一把以上钥匙的人吗?

h3.reject { |v| v.length < 2 }

Or on h2 directly: 或直接在h2

h2.reject { |k, v| v.length < 2 }

I came up with this ugly thing: 我想到了这个丑陋的东西:

h.inject({}) do |memo, (key, array)|
  memo[array[0]] ||= []
  memo[array[0]] << key
  memo
end.detect do |(key, values)|
  values.size > 1
end.last

It basically remaps the hash in the form of: 它基本上以以下形式重新映射哈希:

{first_item_in_array => keys_that_contain_it}

Or, in our case: 或者,在我们的情况下:

{2=>[:k1, :k3]}

Then it just detects the first pair that has more than one match and returns it: 然后,它仅检测具有多个匹配项的第一对并返回:

[:k1, :k3]

Hope that helps! 希望有帮助!

Maybe you can use something like this 也许你可以使用这样的东西

def get_same_first_value(h)
  h.each_with_object(Hash.new { |k, v| k[v] = [] }) do |(sym, arr), exp|
    exp[arr.min] << sym
  end.select { |k, v| v.size != 1 }.values
end

h = {
  :k1 => [2, 3, 5, 12],
  :k2 => [9, 5, 6, 10],
  :k3 => [2, 4, 5, 8],
}

get_same_first_value(h)
# => [[:k1, :k3]]
This is for list of array.
array1 = [1,2,3,4,5,6,7,8,9,10,11,12,13]
myarray = []
myfinalarray = []
array1.each do |item|
    if myarray.size == 3
        myfinalarray.push(myarray)
        myarray = []
    end 
    myarray.push(item)
end 
myfinalarray.push(myarray)
puts "group of 3 items of an array #{myfinalarray}"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM