将数据集合并转换为JSON树

8

假设我有以下数据集。

╔═════════════╦═══════════════╦═══════╗
║  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"}
                ]}
            ]}
        ]
    }
6个回答

2
使用数组。
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! - CRK
@Robert 你需要的是将数据表转换为数组的工具吗? - Joseph
是的!但我不需要像我在问题中问的那样!它意味着按层次结构排列。不同于数据库中的相同!希望你能理解! - CRK
@Robert 是的,我会。可能想要托管一个 SQL 数据库。PHP 可以将查询结果排序为数组。 - Joseph
我可以将查询结果转换为数组,但是这里的问题是要将普通的查询结果转换为一种树形数组。这意味着不应允许重复。 - CRK
显示剩余2条评论

2
您需要的是分组,对吧?试试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);

1
不需要进行合并。我知道你可能正在使用C#进行操作,但我将在Javascript中展示答案,我们知道C#具有数组、哈希映射和JSON序列化器类,因此这应该作为合理的伪代码。
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编码器,它将执行弹出、推送和比较,并在处理集合时附加字符串。


1
你有两种选择:1. 自己动手,2. 让数据库去做。
  1. For a result set as shown in the question (select col1, col2, ... order by col1, col2, ...) you can just parse it in the following way:

    === 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. Here is how you could write a query that exactly gives you the structure using list aggregations (LISTAGG() in orale and GROUP_CONCAT() in mySQL):

    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
    

我不确定这是否对您有所帮助,因为我们不知道数据的确切来源,即它的原始形式,这只是一个想法。 - maraca

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

DataTable MyData = new DataTable();

string Output = "";
Output = JsonConvert.SerializeObject(MyData, Formatting.Indented);

0
例如,假设从数据库返回的查询结果如下(每行仅包含我们需要的内容)。
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']]})

你只需要确保它们存在,不要重复构建。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接