通过合并将数据集转换为JSON树

时间:2015-04-18 06:00:34

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

说我有以下数据集。

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

我希望将其转换为SOMETHING,如下面的JSON格式,以便我可以加载到树视图控件中。最好的方法是什么?主要区别在于合并相同类别或项目! 我可以在C#中解析节点到节点,用前一个节点检查它,如果相同就合并它!并手动创建它,但有没有其他替代方案而不是这个漫长而复杂的过程?

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

6 个答案:

答案 0 :(得分: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]);
            }
        }
    }
}

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

答案 1 :(得分: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);

答案 2 :(得分:1)

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

using Newtonsoft.Json;

DataTable MyData = new DataTable();

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

答案 3 :(得分:1)

无需合并。我意识到你可能在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编码器,它将进行弹出,推送和比较,并在你的集合中附加字符串。

答案 4 :(得分:1)

您有两种可能:1。自己动手,2。让数据库完成工作

  1. 对于问题(=== 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 )中显示的结果集,您只需按以下方式解析它:

    LISTAGG()
  2. 以下是编写查询的方法,该查询使用列表聚合(orale中的GROUP_CONCAT()和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 )精确地为您提供结构:

    id|city
     1|Moscow
     2|London
     3|Москва
    

答案 5 :(得分: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']]})

你只需确定它们是否存在就不再建造它们