2015-04-18 8 views
8

Dire che ho il set di dati di seguito.Set di dati nell'albero JSON unendo

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

voglio trasformare questo in qualcosa di simile al di sotto formato JSON in modo che possa caricare in un controllo TreeView. Quale sarà il modo migliore per farlo? La principale differenza è l'unione della stessa categoria o degli stessi elementi! Posso analizzare il nodo al nodo in C#, controllarlo con il nodo precedente, unirlo se è lo stesso! e crearlo manualmente, ma esistono altre alternative invece di questo processo lungo e complesso?

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

risposta

2

Utilizzare un array.

var products = new Array(); // using new Array() to avoid mess 

    products = 
    [ 
     [ // Home Needs 
      [ 
       "Refrigerator", 
       "red", 
       "$500", 
      ], 
      [ 
       "VacuumCleaner", 
       "white", 
       "$50", 
      ] 
     ], 
     [ // Wearable 
      [ 
       "Applewatch", 
       "Red", 
       "$14, 000", 
      ], 
     ], 
    ] 

Ecco un esempio su come utilizzarlo.

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]); 
      } 
     } 
    } 
} 

Si prega di notare il codice di cui sopra è solo per un esempio. Dovrebbe funzionare bene ma avrei potuto commettere un errore mentre lo scrivevo. Questo era solo per mostrare il mio punto.

+0

Grazie! Ma la domanda è come posso trasformare il set di dati in questo array/JSON! – Robert

+0

@Robert Hai bisogno di qualcosa che possa trasformare una tabella di dati in un array? –

+0

Sì! Ma non ho bisogno come ho chiesto nella domanda! Significa gerarchicamente. Non è lo stesso nel database! Spero che tu capisca! – Robert

1

Provare a utilizzare il framework Json.NET per trasformare un DataSet in una stringa JSON.

using Newtonsoft.Json; 

DataTable MyData = new DataTable(); 

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

Quello di cui hai bisogno è un gruppo di, no?

Prova Linq. Questo è solo un metodo (non testato), ma può dare un ideia da dove cominciare:

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 
            } 
         } 
       }; 

quindi restituire il JSON utilizzando JSON ActionResult del regolatore:

return Json(results); 
1

Non c'è bisogno di fare una fusione. Mi rendo conto che potresti farlo in C# e ti mostrerò la risposta in Javascript, ma sappiamo che C# ha array e HashMaps e una classe JSONSerializer, quindi questo dovrebbe servire come ragionevole pseudocodice.

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))); 

Il trucco è semplice ... qualunque sia la lingua, è necessario essere in grado di dire ...

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

... senza nulla abbaiare a voi. E poi puoi usare uno dei serializzatori JSON disponibili. Il codice dovrebbe essere di facile lettura, anche se non è il bit di codice più performante.

Se la velocità è importante, o lo farai molto, costruire una collezione solo per serializzare e decostruire è costoso. Investi un po 'di tempo a scrivere un codificatore JSON per il tuo oggetto che eseguirà il popping, spingendo e confrontando e aggiungerà le stringhe mentre lavora nella tua raccolta.

1

Hai due possibilità: 1. fai da te, 2.lasciare che il database di fare il lavoro

  1. Per un set di risultati, come illustrato nella questione (select col1, col2, ... order by col1, col2, ...) si può semplicemente analizzarlo nel seguente modo:

    === 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. Ecco come si potrebbe scrivere un query che ti dà esattamente la struttura utilizzando aggregazioni lista (LISTAGG() in orale e 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 
    
.210
+0

Non sono sicuro che questo ti aiuti, perché non sappiamo esattamente da dove provengano i dati, cioè la sua forma originale, è solo un'idea. – maraca

0

Per esempio dicono che la query tornato da database è così (ogni riga, solo qualcosa di cui abbiamo bisogno per qui)

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

basta questo codice in javascript:

Prima di tutto costruire un vuoto oggetto come:

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

poi chiamano questo codice nel tuo foreach o qualsiasi in cui si ottiene ogni valore fila

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']] 
}) 

ho fatto fare un cambio, solo l'ultima parte è array resto è oggetto, la speranza il suo utile, tutto questa linea significa qualcosa come questo

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

è sufficiente per essere sicuri se sono presenti non costruiscili di nuovo