Node.Js - не могу заполнить двумерный массив из объекта, полученного запросом к базе данных

Помогите, пожалуйста, разобраться, что я делаю не так?

На входе у меня есть структура с данными, которую я получаю в результате запроса к базе данных.

   [{
        'data_n': '2020-01-10 10:40',
        'sotrudnik': 'Иванов',
        'dejstvie': 'Поклеил плёнку'
    },
    {
        'data_n': '2020-01-10 11:12',
        'sotrudnik': 'Иванов',
        'dejstvie': 'Помыл машину'
    },
    {
        'data_n': '2020-01-10 15:11',
        'sotrudnik': 'Иванов',
        'dejstvie': 'Выспался'
    }]

Я хочу переложить эти данные в двумерный массив и получить на выходе таблицу:

[ 
  [ 'data_n',           'sotrudnik', 'dejstvie'       ],
  [ '2020-01-10 10:40', 'Иванов',    'Поклеил плёнку' ],
  [ '2020-01-10 11:12', 'Иванов',    'Помыл машину'   ],
  [ '2020-01-10 15:11', 'Иванов',    'Выспался'       ]
]

а получаю [ [], [], [], [] ].

Вот мой код:

// Node.Js

    // исходная структура с данными
    var result = [
        {
            'data_n': '2020-01-10 10:40',
            'sotrudnik': 'Иванов',
            'dejstvie': 'Поклеил плёнку'
        },
        {
            'data_n': '2020-01-10 11:12',
            'sotrudnik': 'Иванов',
            'dejstvie': 'Помыл машину'
        },
        {
            'data_n': '2020-01-10 15:11',
            'sotrudnik': 'Иванов',
            'dejstvie': 'Выспался'
        }];

    var arr_c = [] // вспомогательный массив для формирования строк
    var arr_r = [] // результирующий двумерный массив

        // здесь я кладу заголовки столбцов в нулевую строку
        for (element in result[0]) {
            arr_c.push(element)
        };

        // пробовал разные варианты добавления строки в массив не знаю какой лучше
        arr_r.push(arr_c)
        // arr_r[arr_r.length];
        // arr_r[0] = arr_c;

        // вывожу промежуточное состояния результирующего массива
        console.log(arr_r)

        // очищаю промежуточный массив для дальнейшего использования,
        // тоже какой вариант лучше использовать? 
        arr_c.length = 0;
        // arr_c = [];


        // заполняю таблицу данными
        for (let i = 0; i < result.length; i++) {

            for (element in result[i]) {
                arr_c.push(result[i][element])

            };

        // т.к. в нулевой строке у меня, по логике, должны уже лежать заголовки,
        то строки с данными добавляю начиная с первой
            arr_r[i + 1] = arr_c 

            // вывожу промежуточное состояния результирующего массива
            console.log(arr_r)

        // очищаю промежуточный массив для дальнейшего использования
            arr_c.length = 0 
        };

        // вывожу результат
        console.log(arr_r) // получаю [ [], [], [], [] ]

Вначале я думал, что проблема в асинхронности. Пытался разобраться с коллбэками, промисами, async/await, но понял, что скорее всего
дело в том, что вместо данных в строки записывается ссылка на массив arr_c.

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

[ [ 'data_n', 'sotrudnik', 'dejstvie' ] ]
[
  [ '2020-01-10 10:40', 'Иванов', 'Поклеил плёнку' ],
  [ '2020-01-10 10:40', 'Иванов', 'Поклеил плёнку' ]
]
[
  [ '2020-01-10 11:12', 'Иванов', 'Помыл машину' ],
  [ '2020-01-10 11:12', 'Иванов', 'Помыл машину' ],
  [ '2020-01-10 11:12', 'Иванов', 'Помыл машину' ]
]
[
  [ '2020-01-10 15:11', 'Иванов', 'Выспался' ],
  [ '2020-01-10 15:11', 'Иванов', 'Выспался' ],
  [ '2020-01-10 15:11', 'Иванов', 'Выспался' ],
  [ '2020-01-10 15:11', 'Иванов', 'Выспался' ]
]
[ [], [], [], [] ]

Почему так происходит и как сделать правильно?


Ответы (1 шт):

Автор решения: vsemozhetbyt

Дело в том, что объекты (и в частности массивы) при присваивании не копируются, просто присваивается ссылка на них. Вы используете один и тот же массив в качестве временного буфера и при этом его всё время очищаете — поэтому данные перезаписываются и в конце концов пропадают. Вам нужно каждый раз создавать новый массив. Но ваше преобразование можно сделать проще:

var result = [
  {
    'data_n': '2020-01-10 10:40',
    'sotrudnik': 'Иванов',
    'dejstvie': 'Поклеил плёнку'
  },
  {
    'data_n': '2020-01-10 11:12',
    'sotrudnik': 'Иванов',
    'dejstvie': 'Помыл машину'
  },
  {
    'data_n': '2020-01-10 15:11',
    'sotrudnik': 'Иванов',
    'dejstvie': 'Выспался'
  },
];

const newArray = [
  Object.keys(result[0]),
  ...result.map(obj => Object.values(obj))
];

console.log(newArray);

→ Ссылка