преобразовать вложенный массив javascript в формат csv

Рейтинг: 0Ответов: 1Опубликовано: 14.07.2023

Всем привет! никогда не обращался тут за помощью, но помучавшись сутки над этой жестокой задачки, все же был вынужден отписаться тут.

Мой код проходит почти все проверки, за исключением одного теста, в котором проверяется выброс исключения при передачи в функцию некорректных данных.

вот мой код:

function arrayToCsv(data) {
  const separator = ",";
  let csv = "";

  for (let i = 0; i < data.length; i++) {
    for (let j = 0; j < data[i].length; j++) {
      let value = String(data[i][j]);
      if (value.includes(separator) || value.includes('"') || value.includes("\n") || value.includes("\r")) {
        value = `"${value.replace(/"/g, '""')}"`;
      }
      csv += value;
      if (j !== data[i].length - 1) {
        csv += separator;
      }
      if (typeof data[i][j] === "function") {
        throw new Error("Unexpected value");
      }
    }
    if (i !== data.length - 1) {
      csv += "\n";
    }
  }

  return csv;
}

тут условие:

Нужно написать функцию, которая переводит двумерный массив (массив массивов) в CSV формат и возвращать строку О формате: https://ru.wikipedia.org/wiki/CSV (детали в разделе "Спецификация")

Допустимые значения в качестве элементов массива - числа и строки Если встречается функция - выбрасывать ошибку с текстом "Unexpected value"

Функция принимает: data - массив массивов, содержашие числа или строки

Функция возвращает: Строку в формате CSV

Пример:

arraysToCsv([[1, 2], ['a', 'b']]) /* '1,2
a,b'
*/
arraysToCsv([[1, 2], ['a,b', 'c,d']]) /* '1,2
"a,b","c,d"'
*/

а тут логи тестов :

Ваш ответ не прошел тест!
FAIL test.js
  csvGenerator тест
    ✓ работает в простом случае и аргументах по-умолчанию (4ms)
    ✓ корректно экранирует запятые (1ms)
    ✓ корректно экранирует кавычки
    ✕ выбрасывает ошибку при некорректных данных (4ms)

  ● csvGenerator тест › выбрасывает ошибку при некорректных данных

    expect(received).toThrow(expected)

    Expected message: "Unexpected value"

    Received function did not throw

      79 |     ];
      80 |     for (const data of incorrectDatas) {
    > 81 |       expect(() => arrayToCsv(data)).toThrow(new Error('Unexpected value'));
         |                                      ^
      82 |     }
      83 |   });
      84 | });

      at Object.toThrow test.js:81:38)

Test Suites: 1 failed, 1 total
Tests:       1 failed, 3 passed, 4 total
Snapshots:   0 total
Time:        1.035s
Ran all test suites matching /\/777F523C029F1FE5DFAE1C0D99ADF731\i.
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! frontend-tasks@1.0.0 test:task: `jest "test.js"`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the frontend-tasks@1.0.0 test:task script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     2023-07-14T17_04_41_629Z-debug.log

буду признателен если кто поможет

Ответы

▲ 0Принят

Попробуйте вашу функцию с другими проверками: Проверяем, что входящая data это массив. Далее, что data[i] тоже массив и data[i][j] это строка или число

function arrayToCsv(data) {
  if (!Array.isArray(data)) throw new Error("Unexpected value");
  const separator = ",";
  let csv = "";

  for (let i = 0; i < data.length; i++) {
    if (!Array.isArray(data[i])) throw new Error("Unexpected value");
    for (let j = 0; j < data[i].length; j++) {
      if (typeof data[i][j] !== "string" && typeof data[i][j] !== "number") throw new Error("Unexpected value");
      let value = String(data[i][j]);
      if (value.includes(separator) || value.includes('"') || value.includes("\n") || value.includes("\r")) {
        value = `"${value.replace(/"/g, '""')}"`;
      }
      csv += value;
      if (j !== data[i].length - 1) {
        csv += separator;
      }
    }
    if (i !== data.length - 1) {
      csv += "\n";
    }
  }

  return csv;
}

const vals = [
  [[() => 1+1]],
  [() => 1+1],
  'dsfsd',
  12,
  () => 1+2,
  [12, '2632'],
  [['() => 1 + 3']]
];

vals.forEach(item => {
  try {
    console.log(item, arrayToCsv(item));
  } catch (e) {
    console.log(item, e.message)
  }
})