Как преобразовать объект массива с вложенным комплексом объектов в файл CSV - PullRequest
2 голосов
/ 09 июня 2019

Мне нужна помощь. Я хочу перебрать вложенный объект массива, как показано на рисунке 1, и получить данные в array2D для сохранения данных в файл CSV, но я не очень понимаю, как зацикливать мои данные, чтобы детали становились массивом. Или у кого-то есть другие способы экспортировать данные в файл CSV с таким выводом.


Figure1:

var data = {
  deviceA: {
    smokeSensor: [
      {
        '190501': {
          '0001': 200,
          '0002': 300
        },
      },
      {
        '190502': {
          '0001': 20,
          '0002': 30
        },
      }
    ],
    fireSensor: [
      {
        '190501': {
          '0001': 700,
          '0002': 750
        },
      },
      {
        '190502': {
          '0001': 780,
          '0002': 630
        },
      }
    ]
  },
  deviceB: {
    smokeSensor: [
      {
        '190601': {
          '0001': 100,
          '0002': 110
        },
      },
      {
        '190602': {
          '0001': 120,
          '0002': 130
        },
      }
    ],
    fireSensor: [
      {
        '190601': {
          '0001': 600,
          '0002': 522
        },
      }
    ]
  },
};

Это вывод, который я хочу получить с помощью array2D, чтобы выбросить его в функцию конвертирования array2D в файл CSV.

const rows = [
  ["DeviceA"]
  ["Date/Time", "smokeSensor", "fireSensor"],
  ["190501 00:01", "200", "700"],
  ["190501 00:02", "300", "750"],
  ["190502 00:01", "20", "780"],
  ["190502 00:02", "30", "630"],
  [""],
  ["DeviceB"],
  ["Date/Time", "smokeSensor", "fireSensor"],
  ["190501 00:01", "100", "600"],
  ["190501 00:02", "110", "522"],
  ["190502 00:01", "120", ""],
  ["190502 00:02", "130", ""],
];

Это мой код, который я пытался зациклить, но я довольно ошеломлен, однажды зацикливая каждый цикл, чтобы получить каждую деталь значения для даты и времени. К сожалению, я получил детали, которые были не такими, как хотелось бы.

var dataCSV = []
var mdbName = []
var header = ['DateTime']
var content = []
var dateTime = ''
for (var deviceId in data) {
  mdbName.push(deviceId)
  for (var sensorName in data[deviceId]) {
    header.push(sensorName)
    // console.log(data[deviceId][sensorName]);
    Object.keys(data[deviceId][sensorName]).forEach(item => {
      let date = data[deviceId][sensorName][item]
      for (var key3 in date) {
        // console.log(key3)
        for (var key4 in date[key3]) {
          dateTime = key3 + key4
          // console.log(deviceId + ': ' + sensorName + ': ' + dateTime + ':' + date[key3][key4])
          content.push(date[key3][key4])
        }
      }
    })
  }
}
dataCSV.push(mdbName)
dataCSV.push(header)
dataCSV.push(content)
console.log('End: ', dataCSV)

Это мой плохой вывод:

[ 
  [ 'deviceA', 'deviceB' ],
  [ 'DateTime', 'smokeSensor', 'fireSensor', 'smokeSensor', 'fireSensor' ],
  [ 200, 300, 20, 30, 700, 750, 780, 630, 100, 110, 120, 130, 600, 522 ] 
]

1 Ответ

0 голосов
/ 09 июня 2019

Вы можете использовать что-то вроде следующей функции.Подход заключается в том, чтобы перебирать ключи структуры, группировать значения датчиков по строкам времени и часов / минут и выгружать каждое устройство в строку результатов.Некоторое заполнение сделано, чтобы гарантировать, что строки имеют одинаковую ширину, в соответствии с вашей спецификацией.

Небольшая очистка не помешает, но, похоже, работа сделана (я предполагаю, что ваш вывод DeviceB является опечаткой на "190501", что должно быть "190601" на основе ваших входных данных).

var data = { deviceA: { smokeSensor: [ { '190501': { '0001': 200, '0002': 300 }, }, { '190502': { '0001': 20, '0002': 30 }, } ], fireSensor: [ { '190501': { '0001': 700, '0002': 750 }, }, { '190502': { '0001': 780, '0002': 630 }, } ] }, deviceB: { smokeSensor: [ { '190601': { '0001': 100, '0002': 110 }, }, { '190602': { '0001': 120, '0002': 130 }, } ], fireSensor: [ { '190601': { '0001': 600, '0002': 522 }, } ] }, };

const dataToCSV = data => {
  const rows = [];

  for (const device in data) {
    rows.push(
      [device.replace(/^./, m => m.toUpperCase())], 
      ["Date/Time", ...Object.keys(data[device])]
    );
    const groups = {};
    let longest = 0;

    for (const sensor in data[device]) {  
      for (const time of data[device][sensor]) {
        const k = Object.keys(time)[0];

        for (const hm in time[k]) {
          const groupKey = `${k} ${hm.replace(/(\d\d)(\d\d)/, "$1:$2")}`;

          if (!(groupKey in groups)) {
            groups[groupKey] = [groupKey];
          }

          groups[groupKey].push("" + time[k][hm]);
          longest = Math.max(longest, groups[groupKey].length);
        }
      }
    }

    for (const group of Object.values(groups)) {
      while (group.length < longest) { 
        group.push("");
      }

      rows.push(group);
    }

    rows.push([""]);
  }

  return rows.slice(0, -1);
};

console.log(dataToCSV(data));
...