将第一个属性转换为键

时间:2017-06-01 18:27:52

标签: javascript json csv

我使用以下函数来解析csv文件。

export default function readCsv (csv, reviver) {
  reviver = reviver || function(r, c, v) {
    return v;
  };
  let chars = csv.split(''),
    c = 0,
    cc = chars.length,
    start, end, table = [],
    row;
  while (c < cc) {
    table.push(row = []);
    while (c < cc && '\r' !== chars[c] && '\n' !== chars[c]) {
      start = end = c;
      if ('"' === chars[c]) {
        start = end = ++c;
        while (c < cc) {
          if ('"' === chars[c]) {
            if ('"' !== chars[c + 1]) {
              break;
            } else {
              chars[++c] = '';
            } // unescape ""
          }
          end = ++c;
        }
        if ('"' === chars[c]) {
          ++c;
        }
        while (c < cc && '\r' !== chars[c] && '\n' !== chars[c] && ',' !== chars[c]) {
          ++c;
        }
      } else {
        while (c < cc && '\r' !== chars[c] && '\n' !== chars[c] && ',' !== chars[c]) {
          end = ++c;
        }
      }
      row.push(reviver(table.length - 1, row.length, chars.slice(start, end).join('')));
      if (',' === chars[c]) {
        ++c;
      }
    }
    if ('\r' === chars[c]) {
      ++c;
    }
    if ('\n' === chars[c]) {
      ++c;
    }
  }
  return table;
}

json看起来像这样:

enter image description here

我希望json看起来如下:

[
    doc_id: "16278",
    framework_id: "8078",
    ...
],
[
    doc_id: "16261",
    framework_id: "880",
    ...
],

基本上,不是将第一行的内容作为json中的第一个值,而是将第一行转换为键,将其余行转换为值。

3 个答案:

答案 0 :(得分:3)

对数据进行后期处理以将其映射到所需格式是相对简单的,即给定CSV变量data中的CSV读取器的输出:

data = data.slice(1).map(function(row) {
    return row.reduce(function(obj, value, index) {
        var key = data[0][index];  // extract from first original row
        obj[key] = value;
        return obj;
    }, {});
});

即。迭代所有行(跳过第1行),根据第0行中的键和当前值创建对象。

请注意,这将使用长格式的原始密钥。您可能希望更改第一行中的值以使它们首先更加标准化,例如:

data[0] = data[0].map(function(key) {
    key = key.replace(/[^\w\d\s]/g, ''); // strip non-alphanum or space
    return key.replace(/\s/g, '_').toLowerCase();
});

答案 1 :(得分:0)

这是一种有效的方法:

function csvToKeyedArray(csv) {
  var data = [];
  var keys = csv[0];
  var datum, entry, index;

  for (index in keys) {
    keys[index] = keys[index]
      .replace(/[^\w ]+/g, '') // remove extraneous characters like '?'
      .replace(/ /g, '_') // replace spaces with _
      .toLowerCase();
  }

  for (entry = 1; entry < csv.length; entry++) {
    // initialize an object for each row and add it to the `data` array
    data[entry - 1] = datum = {};

    for (index in keys) {
      // convert rows to objects
      datum[keys[index]] = csv[entry][index];
    }
  }

  return data;
}
然后根据您的规范填充

data

如果您的CSV文件包含10000行,则优于使用.map(),因为每次迭代的函数调用导致的上下文切换开销将导致其明显变慢。

但是,如果您的CSV文件预计只有几百或几千行,那么使用.map()可能会更好,以提高可读性和可维护性。

答案 2 :(得分:-1)

试试这个:

const csvData = `
    id,first_name,last_name,email,gender,ip_address
    1,Jami,Dumingos,jdumingos0@opensource.org,Female,209.112.103.56
    2,Brenda,Harbach,bharbach1@addtoany.com,Female,160.201.233.94
    3,Gail,Rowbrey,growbrey2@sakura.ne.jp,Female,160.199.58.40
    4,Ludvig,Coil,lcoil3@fotki.com,Male,158.37.136.163
    5,Lurlene,Conochie,lconochie4@skyrock.com,Female,145.147.12.44
    6,Aldous,Farrey,afarrey5@cargocollective.com,Male,44.148.54.88
    7,Skipp,Sket,ssket6@discovery.com,Male,81.190.215.227
    8,Greg,Wakefield,gwakefield7@yahoo.com,Male,105.157.167.96
    9,Westley,Purton,wpurton8@mapquest.com,Male,169.67.113.22
    10,Dill,Avraam,davraam9@google.de,Male,223.60.54.101`;

function readCsv(csv, splitMark = ',') {
  const lines = csv.split('\n');
  const keys = lines[0].split(splitMark); // first line as heading
  const rows = lines.slice(1, lines.length - 1);

  return rows.map(row => row
    .split(splitMark)
    .reduce((map, col, index) => {
      map[keys[index]] = col;
      return map;
    }, { }));
}

readCsv(csvData);