开发者

Ruby on Rails: Array to Hash with (key, array of values)

Lets say I have an Array of content_categories (content_categories = user.content_categories)

I now want to add every element belonging to a certain categorie to content_categories with the 开发者_如何学Pythoncategory as a key and the the content-item IDs as elements of a set

In PHP something like this is possible:

foreach ($content_categories as $key => $category) {
  $contentsByCategoryIDArray = Category.getContents($category[id])  
  $content_categories[$key][$contentsByCategoryIDArray]
}

Is there an easy way in rails to do this?

Greets,

Nico


Your question isn't really a Rails question, it's a general Ruby programming question.

Your description isn't very clear, but from what I understand, you want to group IDs for common categories using a Hash. There are various other ways of doing this, but this is easy to understand::

ary = [
  'cat1', {:id => 1},
  'cat2', {:id => 2},
  'cat1', {:id => 3}
]

hsh = {}
ary.each_slice(2) { |a| 
  key,category = a
  hsh[key] ? hsh[key] << category[:id] : hsh[key] = [category[:id]]
}
hsh # => {"cat1"=>[1, 3], "cat2"=>[2]}

I'm using a simple Array with a category, followed by a simple hash representing some object instance, because it makes it easy to visualize. If you have a more complex object, replace the hash entries with those objects, and tweak how you access the ID in the ternary (?:) line.

Using Enumerable.inject():

hsh = ary.each_slice(2).inject({}) { |h,a| 
  key,category = a
  h[key] ? h[key] << category[:id] : h[key] = [category[:id]]
  h 
}
hsh # => {"cat1"=>[1, 3], "cat2"=>[2]}

Enumerable.group_by() could probably shrink it even more, but my brain is fading.


I'd use Enumerable#inject

content_categories = content_categories_array.inject({}){ |memo, category| memo[category] = Category.get_contents(category); memo }


Hash[content_categories.map{|cat|
  [cat, Category.get_contents(cat)]
}]


Not really the right answer, because you want IDs in your array, but I post it anyway, because it's nice and short, and you might actually get away with it:

content_categories.group_by(&:category)


content_categories.each do |k,v|
  content_categories[k] = Category.getContents(v)
end

I suppose it's works


If i understand correctly, content_categories is an array of categories, which needs to be turned into a hash of categories, and their elements.

content_categories_array = content_categories
content_categories_hash = {}
content_categories_array.each do |category| 
  content_categories_hash[category] = Category.get_contents(category)
end
content_categories = content_categories_hash

That is the long version, which you can also write like

content_categories = {}.tap do |hash|
  content_categories.each { |category| hash[category] = Category.get_contents(category) }
end 


For this solution, content_categories must be a hash, not an array as you describe. Otherwise not sure where you're getting the key.

contents_by_categories = Hash[*content_categories.map{|k, v| [k, Category.getContents(v.id)]}]
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜