2016-12-07 1 views
1

Ich habe ein Array mit verschachtelten Objekten, wie diese:Wie konvertiert man ein Array verschachtelter Objekte in CSV?

[ 
    {"name": "1", "children": [{"name": "1.1", "children":"1.2"}]}, 
    {"id": "2", "thing": [{"name": "2.1", "children":"2.2"}]}, 
    {"name": "3", "stuff": [{"name": "3.1", "children":"3.2"}]}, 
] 

Die Objekte Werte von verschiedenen Typen, einschließlich anderen, verschachtelten Objekten enthalten können.

Ich möchte dieses Array in CSV-Format konvertieren.

Ich habe versucht, mit for .. in Schleifen, regelmäßige verschachtelte for Schleifen, .map() und Rekursion zu iterieren. Ich denke, dass Rekursion die einzige Möglichkeit ist, dieses spezielle Problem zu lösen. Für die CSV-Feldnamen möchte ich die Reihenfolge der Schlüssel verwenden, die zu dem Wert führen.

Für das gegebene Beispiel, das CSV Ergebnis ich suche ist:

name, children.name, children.children,id, thing.name, thing.children, stuff.name, stuff.children 
1, 1.1, 1.2, 
,,,2,2.1,2.2 
3,,,,3,3.1,3.2 
+0

[Es gibt nicht so etwas wie ein JSON-Objekt.] (Http://benalman.com/news/2010/03/theres-no-such-thing-as-a -json /) – nicovank

+1

Und was ist, wenn Sie 2 verschachtelte "Kinder" -Objekte haben? – zerkms

+1

@nicovank - gehen Sie hier, um herauszufinden, was JSON ist ?? http://www.json.org/ – user1789573

Antwort

4

Sie könnten diese ES6 Funktion verwenden, um die 2D-Array zu erstellen, die Sie suchen, was können Sie dann in das CSV leicht umwandeln :

function pivot(arr) { 
 
    var mp = new Map(); 
 
    
 
    function setValue(a, path, val) { 
 
     if (Object(val) !== val) { // primitive value 
 
      var pathStr = path.join('.'); 
 
      var i = (mp.has(pathStr) ? mp : mp.set(pathStr, mp.size)).get(pathStr); 
 
      a[i] = val; 
 
     } else { 
 
      for (var key in val) { 
 
       setValue(a, key == '0' ? path : path.concat(key), val[key]); 
 
      } 
 
     } 
 
     return a; 
 
    } 
 
    
 
    var result = arr.map(obj => setValue([], [], obj)); 
 
    return [[...mp.keys()], ...result]; 
 
} 
 

 
function toCsv(arr) { 
 
    return arr.map(row => 
 
     row.map (val => isNaN(val) ? JSON.stringify(val) : +val).join(',') 
 
    ).join('\n'); 
 
} 
 

 
// Sample data 
 
var arr = [ 
 
    {"name": "1", "children": [{"name": "1.1", "children":"1.2"}]}, 
 
    {"id": "2", "thing": [{"name": "2.1", "children":"2.2"}]}, 
 
    {"name": "3", "stuff": [{"name": "3.1", "children":"3.2"}]}, 
 
]; 
 

 
// Conversion to 2D array and then to CSV: 
 
console.log(toCsv(pivot(arr)));
.as-console-wrapper { max-height: 100% !important; top: 0; }

Für andere Möglichkeiten

ein 2D-Array zu CSV finden Sie in diesemzu konvertieren.

+0

vielen Dank! Ich hatte keine Ahnung von der JS-Kartenfunktionalität mit den Ellipsen. – user1789573

0

Dies ist ein ES5-Vorschlag.

Sie könnten das Array iterieren und die Schlüssel in einer Hash-Tabelle sammeln und die Daten später mit den Lücken speichern.

var data = [{ name: "1", children: [{ name: "1.1", children: "1.2" }] }, { id: "2", thing: [{ name: "2.1", children: "2.2" }] }, { name: "3", stuff: [{ name: "3.1", children: "3.2" }] }], 
 
    csv = function (array) { 
 
     var cols = [], 
 
      collection = Object.create(null), 
 
      i = -1, 
 
      toCSV = function (v) { return isNaN(v)? JSON.stringify(v): v; }, 
 
      csv; 
 

 
     array.forEach(function iter(path) { 
 
      return function (o) { 
 
       path.length || i++; 
 
       Object.keys(o).forEach(function (k) { 
 
        if (Array.isArray(o[k])) { 
 
         o[k].forEach(iter(path.concat(k))); 
 
         return; 
 
        } 
 
        var key = path.concat(k).join('.'); 
 
        if (!collection[key]) { 
 
         cols.push(key); 
 
         collection[key] = []; 
 
        } 
 
        collection[key][i] = o[k]; 
 
       }); 
 
      }; 
 
     }([])); 
 

 
     csv = cols.map(toCSV).join() + '\n'; 
 
     for (i = 0; i < array.length; i++) { 
 
      csv += cols.map(function (k) { return toCSV(collection[k][i]); }).join() + '\n'; 
 
     } 
 
     return csv; 
 
    }(data); 
 

 
console.log(csv);

Verwandte Themen