Как разобрать JS объект, содержащий массивы, для использования в модуле json2csv в JavaScript? - PullRequest
1 голос
/ 06 августа 2020

У меня есть массив (arr) объектов, каждый из которых выглядит следующим образом: -

{
   "name" : "someName",
   "address" : "someAddress",
   "attributes" : [
      {
        "attName" : "Sea",
      },
      {
        "attName" : "Beach",
      }
    ],
   "values" : [ 
      "2540",
      "3345",
      "2340"
    ]
}

Массивы «значения» и «атрибуты» могут иметь разное количество элементов для разных объектов.

Теперь, когда я конвертирую этот массив объектов в csv с помощью этого кода:

const json2csv = require('json2csv').parse;
const csvString = json2csv(arr);

, я получаю следующий результат:

name, address, attributes, values
"someName","someAddress", [{"attName" : "Sea"},{"attName" : "Beach"}], ["2540", "3345", "2340"]

Однако я хочу, чтобы мой csv был примерно таким: это:

name, address, attName, attName, value, value, value
"someName","someAddress", "Sea", "Beach", "2540", "3345", "2340"

Я знаю, что JSON не позволяет использовать несколько ключей с одинаковым именем, но я не могу понять, как этого добиться.

1 Ответ

0 голосов
/ 06 августа 2020

Расширение столбца массива в несколько столбцов с одинаковым заголовком нестандартно.

Однако, если вы действительно хотите это сделать, вы можете написать собственную функцию для преобразования массива объектов в 2D-строку массив. Затем используйте библиотеку для преобразования массива 2D строк в csv.

Например:

// import a library to convert 2d string array into csv string
let { to_csv } = require("@beenotung/tslib/csv");

// the sample object array
let records = [{
        "name": "someName",
        "address": "someAddress",
        "attributes": [
            {
                "attName": "Sea",
            },
            {
                "attName": "Beach",
            }
        ],
        "values": [
            "2540",
            "3345",
            "2340"
        ]
    }];

let csv = object_array_to_csv(records)
console.log(csv);
/* will print out below lines:
name,address,attName,attName,values,values,values
someName,someAddress,Sea,Beach,2540,3345,2340
*/

// convert an object array into csv text
function object_array_to_csv(objects) {
    let records = objects.map(object_to_opt_list);
    let titles = records.find(record => record.length > 0)
        .map(field => field.key);
    let values = records.map(record => record.map(field => field.value));
    let rows = [titles, ...values];
    let csv = to_csv(rows);
    return csv;
}

// convert an object with string and array of string/object into 2d key-value array
function object_to_opt_list(object) {
    let opt_list = [];
    for (const [key, value] of Object.entries(object)) {
        if (Array.isArray(value)) {
            opt_list.push(...value_to_opt_list(key, value));
        }
        else {
            opt_list.push({ key, value });
        }
    }
    return opt_list;
}

// convert recursively expand the array/object value into 2d key-value array
function value_to_opt_list(key, value) {
    if (Array.isArray(value)) {
        return value.map(value => value_to_opt_list(key, value))
            .reduce((acc, c) => acc.concat(c));
    }
    if (typeof value === "object") {
        return object_to_opt_list(value);
    }
    return [{ key, value }];
}
...