【问题标题】:Dynamic menu with Mongoid in SinatraSinatra 中带有 Mongoid 的动态菜单
【发布时间】:2014-05-05 03:14:25
【问题描述】:

我正在构建 Sinatra/Mongoid 应用程序,我想在 MongoDB 的文档中创建数组值的动态菜单。我猜以下算法:
假设在 Mongo 中存储了一些文档

{ "name": "doc1", "array": ["foo", "bar", "baz", "quux"] }
{ "name": "doc2", "array": ["foo", "baz"] }
{ "name": "doc3", "array": ["bar", "baz", "quux"] }
{ "name": "doc4", "array": ["quux"] }
{ "name": "doc5", "array": ["foo", "quux"] }

现在我想应该

  1. 向所有文档询问“数组”字段值,
  2. 然后按提及次数对值进行排序,
  3. 删除重复值
  4. 在我看来,给我这个新数组来构建%ul,就像这样:

    %ul
      %li foo
      %li bar
      %li baz
      %li quux
    

我不知道如何实现。

提前感谢您的帮助。

【问题讨论】:

  • 我不知道我是否完全理解您的问题。您可以从上面的示例输入中添加一个 HTML/HAML/whatever sn-p 以及所需的输出吗?
  • 类似this
  • 我已将您的 sn-p 纳入您的问题中。

标签: ruby algorithm mongodb sinatra mongoid


【解决方案1】:

假设您已经有一个 arrays 变量,其中包含文档的“数组”值:

arrays = [
  ["foo", "bar", "baz", "quux"],
  ["foo", "baz"],
  ["bar", "baz", "quux"],
  ["quux"],
  ["foo", "quux"]
]

在这种情况下,我将使用哈希将数组值存储为键,并使用计数器存储值。这允许

  1. 消除重复输入,并且
  2. 创建一个用于排序的句柄。

有趣的是inject 方法,它迭代一个可枚举并注入一个累加器(memo):

list = arrays.flatten.inject({}) do |memo, e|
  memo[e] = (memo[e] || 0) + 1
  memo
end
#=> [["foo", 3], ["bar", 2], ["baz", 3], ["quux", 4]]

这会创建这个list,然后可以对其进行排序:

list = list.sort{|a,b| a[1] <=> b[1] }
#=> [["bar", 2], ["foo", 3], ["baz", 3], ["quux", 4]]

并过滤:

list = list.map(&:first)
#=> ["bar", "foo", "baz", "quux"]

然后您可以在视图中迭代该数组。


注意我通常会尝试多压缩inject 调用,像这样

list = arrays.flatten.inject({}) do |memo, e|
  (memo[e] ||= 0) += 1
  memo
end

list = arrays.flatten.inject(Hash.new {|h,k| h[k]=0 }) do |memo, e|
  memo[e] += 1
  memo
end

……但由于某种原因,我的 Ruby 目前认为这是一个语法错误。也许只是缺少咖啡;-)

【讨论】:

    猜你喜欢
    • 2010-11-29
    • 1970-01-01
    • 2013-10-20
    • 1970-01-01
    • 2012-03-03
    • 1970-01-01
    • 2017-10-27
    • 2013-10-01
    • 1970-01-01
    相关资源
    最近更新 更多