循环遍历yaml集合,按键排序

时间:2017-01-29 19:39:53

标签: ruby yaml erb

erb - 模板中,我想循环遍历yaml-collection,例如:

collection:
  - title: "title a"
    year: 2017
  - title: "title b"
    year: 2017
  - title: "title b"
    year: 2016
  - ...

在输出文件(格式为markdown)中,我想按年份对不同的条目进行排序并拆分它们,而不事先知道当年存在哪个values - key

# 2017
* title a  
* title b

# 2016 
* title c
…

这可以通过Ruby中的each do循环来实现吗?

关注

我有一个后续问题。下面给出的解决方案很好。现在,我希望能够在我的ERB模板中使用由此实现的排序/组功能。以下代码输出所需的结果。但是如何在ERB模板中调用此排序/组功能,以便在" conferencecontribution"收集是相应的订单?

(作为旁注,YAML文件还包括需要订购的其他集合,因此将它作为一个函数可能是有意义的吗?)

dataset = YAML.load_file('cv.de.yaml')

dataset['conferencecontributions'].group_by { |hash| hash['year'] }
      .sort_by  { |year, _| -year }
      .each do |year, entries|
  puts "# #{year}"
  entries.each do |entry|
    puts "* #{entry["title"]} #{entry["location"]}"
  end
  puts
 end

2 个答案:

答案 0 :(得分:2)

您需要多个group_bysort_by

require 'yaml'

collection = YAML::load(%q{
collection:
  - title: "title a"
    year: 2017
  - title: "title b"
    year: 2017
  - title: "title c"
    year: 2016})["collection"]


collection.group_by { |hash| hash['year'] }
          .sort_by  { |year, _| -year }
          .each do |year, entries|
  puts "# #{year}"
  entries.map { |entry| entry['title'] }.sort.each do |title|
    puts "* #{title}"
  end
  puts
end

输出:

# 2017
* title a
* title b

# 2016
* title c

答案 1 :(得分:1)

回答你的后续问题(可能应该作为一个单独的问题发布):是的,你应该为此定义一个方法,如下所示:

def by_year(data, &block)
  years = data.group_by {|hash| hash['year'] }
      .sort_by  {|year,| -year }
  block ? years.each(&block) : years
end

然后你会在ERB中使用它:

<% by_year(dataset['conferencecontributions']) do |year, entries| %>
  <h1><%= year %></h1>
  <ul>
  <% entries.each do |entry| %>
    <li><%= entry["title"] %>, <%= entry["location"] %></li>
  <% end %>
  </ul>
<% end %>

在repl.it上查看:https://repl.it/F3Vl