【问题标题】:String to Object with JavaScript使用 JavaScript 将字符串转换为对象
【发布时间】:2017-04-04 22:06:02
【问题描述】:

我想知道在 JavaScript 中将此字符串转换为对象的最有效方法。

这是丑陋的字符串:

  "\"date\",\"initRegistrations\",\"registrations\",\"finalizeRegistrations\"\r\n\"03/29/2017\",\"0\",\"0\",\"0\"\r\n\"03/30/2017\",\"5\",\"4\",\"4\"\r\n\"03/31/2017\",\"42\",\"0\",\"0\"\r\n\"04/01/2017\",\"192\",\"0\",\"0\"\r\n\"04/02/2017\",\"4\",\"0\",\"0\"\r\n\"04/03/2017\",\"23\",\"0\",\"0\"\r\n\"04/04/2017\",\"5\",\"0\",\"0\"\r\n"

目前我正在使用这个函数,但它不能正常工作,预期的输出将是一个带有键日期、initRegistrations、registrations、finalizeRegistrations 的对象对象:

   function convertToArrayOfObjects(data) {
    var keys = data.shift(),
        i = 0, k = 0,
        obj = null,
        output = [];

    for (i = 0; i < data.length; i++) {
        obj = {};

        for (k = 0; k < keys.length; k++) {
          if(data[i][k]){
            obj[keys[k]] = data[i][k];
          }

        }

        output.push(obj);
    }

    return output;
}

有没有什么花哨的方法可以轻松实现这一点,或者我应该去玩我的对象数组? 任何帮助或建议表示赞赏。 谢谢。

【问题讨论】:

  • 你的“丑陋字符串”是字符串的文字内容还是字符串文字?
  • 该字符串的预期输出是什么?
  • “不能正常工作”,它应该如何工作?预期与实现的输出是什么?
  • 这些数据是从哪里来的?看起来 CSV 或带有所有双引号和行尾的 CSV 都以 JSON 格式转义了。如果你知道它是如何编码的,那么解码它会容易得多。
  • 您指定了输入,现在请指定所需的输出

标签: javascript arrays string object


【解决方案1】:

可能对某些人来说太实用了,但我就是这样写的。

const s =   "\"date\",\"initRegistrations\",\"registrations\",\"finalizeRegistrations\"\r\n\"03/29/2017\",\"0\",\"0\",\"0\"\r\n\"03/30/2017\",\"5\",\"4\",\"4\"\r\n\"03/31/2017\",\"42\",\"0\",\"0\"\r\n\"04/01/2017\",\"192\",\"0\",\"0\"\r\n\"04/02/2017\",\"4\",\"0\",\"0\"\r\n\"04/03/2017\",\"23\",\"0\",\"0\"\r\n\"04/04/2017\",\"5\",\"0\",\"0\"\r\n";

// Remove surrounding quotes from a string.
const removeQuotes = s => s.replace(/^"|"$/g, '');

// Split input by newline ('\r\n')
const lines = s.trim().split('\r\n');

// Get header (first line of input) and remove quotes.
const header = lines[0].split(',').map(removeQuotes)

// The rest of the string is data. Split by comma and remove quotes.
const data = lines.splice(1).map(line => line.split(',').map(removeQuotes));

// Given header row and data row, combine into an object.
const zipWith = header => row => {
  return header.reduce((map, item, index) => {
    map[item] = row[index];
    return map;
  }, {});
}

// Now process all your data with a map :)
const result = data.map(zipWith(header));

console.log(result);

非常确定输出正是您想要的:

[
  {
    "date": "03/29/2017",
    "initRegistrations": "0",
    "registrations": "0",
    "finalizeRegistrations": "0"
  },
  {
    "date": "03/30/2017",
    "initRegistrations": "5",
    "registrations": "4",
    "finalizeRegistrations": "4"
  },
  {
    "date": "03/31/2017",
    "initRegistrations": "42",
    "registrations": "0",
    "finalizeRegistrations": "0"
  },
  {
    "date": "04/01/2017",
    "initRegistrations": "192",
    "registrations": "0",
    "finalizeRegistrations": "0"
  },
  {
    "date": "04/02/2017",
    "initRegistrations": "4",
    "registrations": "0",
    "finalizeRegistrations": "0"
  },
  {
    "date": "04/03/2017",
    "initRegistrations": "23",
    "registrations": "0",
    "finalizeRegistrations": "0"
  },
  {
    "date": "04/04/2017",
    "initRegistrations": "5",
    "registrations": "0",
    "finalizeRegistrations": "0"
  }
]

【讨论】:

  • 很棒的东西@Triptych,奇特的解决方案!
  • @Victor 谢谢!在这一点上,这段代码对我来说比其他答案更简单。函数式编程完全值得投资 =)
【解决方案2】:

您可能正在寻找 split,它可以从字符串中创建一个数组:

var a = s.split("\r\n");

这将为您提供一个字符串包含的行数组。然后,如果您需要每行中的字段,您可以在 for 循环中使用另一个分隔符(逗号?)进一步 split

var tbl=[];
var rows = s.split("\r\n");
for(var y in rows) {
    var row = rows[y].split('"');
    tbl.push(row);
} 

这将为您提供一个数组数组。只需最少的努力,您就可以改进它以识别带有字段名称的标题行,然后将它们用作每行的键。 (注意:我现在在移动设备上,所以这是我能为您做的最好的事情,但如果您仍然迷路,我可以稍后再向您展示更详细的示例。)

【讨论】:

  • 嗨@dkellner 感谢您的帮助,这只是构建一个字符串数组。我认为完美的东西应该是对象的对象,或者对象的数组。
  • 瞧,又近了一步。
猜你喜欢
  • 2018-05-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-16
  • 1970-01-01
  • 2011-10-05
  • 2013-04-09
  • 2019-03-11
相关资源
最近更新 更多