【问题标题】:Dataset to JSON tree by merging通过合并将数据集转换为 JSON 树
【发布时间】:2015-06-25 03:37:52
【问题描述】:

假设我有以下数据集。

╔═════════════╦═══════════════╦═══════╗
║  Category   ║     Item      ║ Color ║
╠═════════════╬═══════════════╬═══════╣
║ Electronics ║ Mobile        ║ Black ║
║ Electronics ║ Mobile        ║ Green ║
║ Electronics ║ Laptop        ║ Black ║
║ HomeNeeds   ║ VaccumCleaner ║ white ║
║ HomeNeeds   ║ Refrigerator  ║ Red   ║
║ Wearable    ║ AppleWatch    ║ Red   ║
╚═════════════╩═══════════════╩═══════╝

我想将它转换成类似于下面的 JSON 格式,以便我可以加载到树视图控件中。最好的方法是什么?主要区别在于合并相同的类别或项目! 我可以在 C# 中解析节点到节点,与前一个节点检查,如果相同则合并!并手动创建它,但是除了这个漫长而复杂的过程,还有其他选择吗?

{
    "Categories" : [
        {"Electronics" : [
                {"Mobile" : [
                    {"color":"Black"},
                    {"color":"Green"}
                    ]},
                {"Laptop":[
                    {"color":"Black"}
                    ]}
            ]},
        {"HomeNeeds":[
            {"VaccumCleaner": [
                    {"color":"white"}
                ]},
            {"Refrigerator":[
                {"color": "Red"}
                ]}
            ]},
        {"Wearable":[
            {"Applewatch":[
                {"color":"Red"}
                ]}
            ]}
        ]
    }

【问题讨论】:

    标签: javascript asp.net json c#-4.0 serialization


    【解决方案1】:

    使用数组。

    var products = new Array(); // using new Array() to avoid mess
    
       products = 
        [
            [ // Home Needs
                [
                    "Refrigerator",
                    "red",
                    "$500",
                ],
                [
                    "VacuumCleaner",
                    "white",
                    "$50",
                ]
            ],
            [ // Wearable
                [
                    "Applewatch",
                    "Red",
                    "$14, 000",
                ],
            ],
        ]
    

    这是一个关于如何使用它的示例。

    function getInfoOn(category,nameofappliance) { // 0 for category is home needs, etc
        for (var i=0; i < products[category].length; i++) {
            for(var l=0; l < products[i].length; l++) {
                for (var b=0; b < i[category][l].length; b++) {
                    console.log('Name: '+ i[category][l][0]);
                    console.log('Price: '+i[category][l][2]);
                }
            }
        }
    }
    

    请注意以上代码仅作为示例。它应该可以正常工作,但是我在编写它时可能犯了一个错误。这只是为了说明我的观点。

    【讨论】:

    • 谢谢!但问题是我如何将数据集转换为这个数组/JSON!
    • @Robert 您需要将数据表转换为数组的东西吗?
    • 是的!但我不需要我在问题中提出的问题!是层次分明的意思。在数据库中不一样!希望你能理解!
    • @Robert 是的,我愿意。可能想要托管一个 SQL 数据库。 PHP 可以将查询结果排序到一个数组中。
    • 我可以将查询结果转换为数组,但这里的处理是将普通查询结果转换为树型数组。这意味着不应该允许重复。,
    【解决方案2】:

    尝试使用 Json.NET 框架将 DataSet 转换为 JSON 字符串。

    using Newtonsoft.Json;
    
    DataTable MyData = new DataTable();
    
    string Output = "";
    Output = JsonConvert.SerializeObject(MyData, Formatting.Indented);
    

    【讨论】:

      【解决方案3】:

      您需要的是分组,不是吗?

      试试 Linq。这只是一种(未经测试的)方法,但可以让您知道从哪里开始:

      var results = from c in dataset
                    group c by c.Category into cGrouped
                    select new {
                       Category = cGrouped.Category,
                       Items = from i in cGrouped
                               group i by i.Item into iGrouped
                               select new {
                                  Item = iGrouped.Item
                                  Colors = from cl in iGrouped
                                           group cl by cl.Color into clGrouped
                                           select new {
                                              Color = cl.Color
                                           }
                               }
                    };
      

      然后使用控制器的Json ActionResult返回json:

      return Json(results);
      

      【讨论】:

        【解决方案4】:

        无需进行合并。我知道您可能在 C# 中执行此操作,我将在 Javascript 中向您展示答案,但我们知道 C# 具有数组和 HashMaps 以及 JSONSerializer 类,因此这应该作为合理的伪代码。

        var data = [
            ['Electronics', 'Mobile', 'Black'],
            ['Electronics', 'Mobile', 'Green'],
            ['Electronics', 'Laptop', 'Black'],
            ['HomeNeeds', 'VaccumCleaner', 'white'],
            ['HomeNeeds', 'Refigerator', 'Red'],
            ['Wearable', 'AppleWatch', 'Red']
        ];
        
        function force(collection, key) {
            if (!collection[key]) collection[key] = {};
            return collection[key];
        }
        
        function tableToTree(data) {
            var result = {};
            data.forEach(function(item) {
                force(force(result, item[0]), item[1]).color = item[2];
            });
            return result;
        }
        
        console.log(JSON.stringify(tableToTree(data)));
        

        诀窍很简单...无论是什么语言,您都需要能够说...

        result[category][item]["color"] = color;
        

        ...没有任何东西对你吠叫。然后您可以使用其中一种可用的 JSON 序列化程序。代码应该易于阅读,即使它不是绝对性能最高的代码。

        如果速度很重要,或者您会经常这样做,那么构建一个仅用于序列化和解构它的集合是很昂贵的。花点时间为您的对象编写一个 JSON 编码器,该编码器将执行弹出、推送和比较,并在您的集合中添加字符串。

        【讨论】:

          【解决方案5】:

          你有两种可能:1.自己做,2.让数据库做

          1. 对于问题 (select col1, col2, ... order by col1, col2, ...) 中显示的结果集,您可以通过以下方式对其进行解析:

            === simplified algorithm in pseudo code ===
            init old column values to a unique value (e.g. null if not used)
            loop over the result set:
               test the columns from left to right:
               if old column X <> column X
                  add column X and all values to the right to the datastructure
            
          2. 您可以通过以下方式编写查询,使用列表聚合(orale 中的LISTAGG() 和 mySQL 中的GROUP_CONCAT())准确地为您提供结构:

            SELECT
              '{' ||
                LISTAGG(O.S, ',')
                  WITHIN GROUP (ORDER BY O.S) ||
              '}'
            FROM
              (SELECT
                O.Category Category, -- (*)
                '{"' || O.Category '":[' ||
                  LISTAGG(O.S, ',')
                    WITHIN GROUP (ORDER BY O.S) ||
                  ']}'
                S
              FROM
                (SELECT
                  T.Category Category,
                  T.Item Item, -- (*)
                  '{"' || T.Item || '":[' ||
                    LISTAGG('{"color":"' || T.Color || '"}', ',')
                      WITHIN GROUP (ORDER BY T.Color) ||
                    ']}'
                  S
                FROM
                  Table T
                GROUP BY
                  T.Category, T.Item
                ORDER BY
                  T.Category, T.Item  
                ) O
              GROUP BY
                O.Category
              ORDER BY
                O.Category
              ) O
            ;
            
            -- (*) probably required because of GROUP BY
            

          【讨论】:

          • 我不确定这是否对您有帮助,因为我们不知道数据的确切来源,即其原始形式,这只是一个想法。
          【解决方案6】:

          例如说从数据库返回的查询是这样的(每一行,这里只需要我们需要的东西)

          var row = {'Category': 'value', 'Item': 'value', 'Color': 'value'}
          

          您只需要在 javascript 中编写此代码:

          首先构建一个空对象,如:

          var object = {} or window.object = {}
          

          然后在你的 foreach 或任何你得到每一行值的地方调用这个代码

          if(object['Category'] == undefined)
            object['Category'] = {}
          if(object['Category'][row['Category']] == undefined)
            object['Category'][row['Category']] = {}
          if(object['Category'][row['Category']][row['Item']] == undefined)
            object['Category'][row['Category']][row['Item']] = []
          object['Category'][row['Category']][row['Item']].push({
              ['Color'] : {[row['Color']]
          })
          

          我确实做了一个改变,只有最后一部分是数组,其余部分是对象,希望它有帮助,所有这行都是这样的

          object['Category'][row['Category']][row['Item']].push({['Color'] : {[row['Color']]})
          

          您只需要确定它们是否存在就不要再次构建它们

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2017-01-23
            • 1970-01-01
            • 2016-01-27
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-05-26
            相关资源
            最近更新 更多