webs86
webs86

Reputation: 319

ruby - Array group_by sub elements

I need to group this YAML strutcture by array elements.

This is example of my YAML structure:

articles:
  - title: 'Title 1'
    url: 'https://example.com'
    data: July 21, 2017
    categories:
      - 'category 1'
      - 'category 2'
  - title: 'Title 2'
    url: 'https://example.com'
    data: July 23, 2017
    categories:
      - 'category 2'

Result I need is this or similar:

['category 1' => 
    [
        {title: 'Title 1', url: 'https://example.com', data: July 21, 2017, categories: ['category 1', 'category 2']}
    ], 
    'category 2' => [
        {title: 'Title 1', url: 'https://example.com', data: July 21, 2017, categories: ['category 1', 'category 2']},
        {title: 'Title 2', url: 'https://example.com', data: July 23, 2017, categories: ['category 2']}
    ]
]

Can you help me? Thank you in advance

UPDATE:

I have tried this:

articles.group_by(&:categories).map{|v, a| [v, a] }

but key is not single category, but categories elements. I think I need a more loop but after some trials I haven't get the result.

Sorry for this, but I newbie for ruby

UPDATE 2: Wrong result is:

[
  [
    [
      "category 1",
      "category 2"
    ],
    [
      {
        "title": "Title 1",
        "url": "https://example.com",
        "data": "July 21, 2017",
        "categories": [
          "category 1",
          "category 2"
        ]
      }
    ]
  ],
  [
    [
      "category 2"
    ],
    [
      {
        "title": "Title 2",
        "url": "https://example.com",
        "data": "July 23, 2017",
        "categories": [
          "category 2"
        ]
      }
    ]
  ]
]

Upvotes: 0

Views: 116

Answers (2)

Aleksei Matiushkin
Aleksei Matiushkin

Reputation: 121000

It seems, in this case, the plain old good reducer would suit your needs better:

articles.each_with_object({}) do |article, acc|
  acc.merge! article.categories.map { |c| [c, article] }.to_h
end

or even:

articles.map do |article|
  article.categories.map { |c| [c, article] }.to_h
end.reduce(&:merge)

Upvotes: 2

B.G.
B.G.

Reputation: 6016

Do you need a group_by? Why not an easy nested loop?

result = {}
articels.each do |article|
  article.categories.each do |cat|
    result[cat] ||= []
    result[cat] << article
  end
end

Upvotes: 1

Related Questions