将产品和类别的平面列表转换为树结构

时间:2016-02-08 19:29:25

标签: ruby hash tree

我目前有以下结构中的项目:

[{
    "category" => ["Alcoholic Beverages", "Wine", "Red Wine"],
    "name" => "Robertson Merlot",
    "barcode" => '123456789-000'
    "wine_farm" => "Robertson Wineries",
    "price" => 60.00
}]

我已经编制了这些数据,但我使用的数据结构相同,我无法更改数据。

我有>其中10万个。

每个产品都嵌套在1和n(无限制)类别之间。

由于此数据的表格性质,因此会重复这些类别。我想使用树数据来防止这种重复,并将文件大小减少25%到30%。

我的目标是这样的树结构:

{
    "type" => "category",
    "properties" => {
        "name" => "Alcoholic Beverages"
    },
    "children" => [{
                       "type" => "category",
                       "properties" => {
                           "name" => "Wine"
                       },
                       "children" => [{
                                          "type" => "category",
                                          "properties" => {
                                              "name" => "Red Wine"
                                          },
                                          "children" => [{
                                                             "type" => "product",
                                                             "properties" => {
                                                                 "name" => "Robertson Merlot",
                                                                 "barcode" => '123456789-000',
                                                                 "wine_farm" => "Robertson Wineries",
                                                                 "price" => 60.00
                                                             }
                                                         }]

                                      }]
                   }]
}
  1. 我似乎无法想到一个有效的算法来实现这一目标。我希望在正确的方向上提供任何帮助。

  2. 我应该生成ID并为每个节点添加父ID吗?我担心使用ID会增加文本的长度,我试图缩短。

2 个答案:

答案 0 :(得分:1)

虽然我已经从您请求的结构中简化了一下,但您可以使用逻辑来了解如何完成它:

require 'pp'
x = [{
    "category" => ["Alcoholic Beverages", "Wine", "Red Wine"],
    "name" => "Robertson Merlot",
    "barcode" => '123456789-000',
    "wine_farm" => "Robertson Wineries",
    "price" => 60.00
}]

result = {}

x.each do |entry|

  # Save current level in a variable
  current_level = result

  # We want some special logic for the last item, so let's store that.
  item = entry['category'].pop


  # For each category, check if it exists, else add a category hash.
  entry['category'].each do |category|
    unless current_level.has_key?(category)
      current_level[category] = {'type' => 'category', 'children' => {}, 'name' => category}
    end
    current_level = current_level[category]['children'] # Set the new current level of the hash.
  end

  # Finally add the item:
  entry.delete('category')
  entry['type'] = 'product'
  current_level[item] = entry

end

pp result

它给了我们:

{"Alcoholic Beverages"=>
  {"type"=>"category",
   "children"=>
    {"Wine"=>
      {"type"=>"category",
       "children"=>
        {:"Red Wine"=>
          {"name"=>"Robertson Merlot",
           "barcode"=>"123456789-000",
           "wine_farm"=>"Robertson Wineries",
           "price"=>60.0,
           "type"=>"product"}},
       "name"=>"Wine"}},
   "name"=>"Alcoholic Beverages"}}

答案 1 :(得分:0)

有可能更容易实现这一点,但这是我现在所能想到的,它应该与你的结构相匹配。

var x = d3.event.x
  var y = d3.event.y
  d3.select(this)
    .attr('transform', 'translate(' + x + ',' + y + ')')