将此字符串转换为对象

时间:2018-02-23 09:28:58

标签: javascript

我有这个字符串(称为数据)

||id: ticket/327364|Subject: TestSubject|Due: 2018||--||id: ticket/327366|Subject: TestTwo|Due: 2018|||

我想变成一个可以使用键/值访问的对象。 第1步是将字符串拆分为“ - ”并删除所有“|”迹象。我喜欢这个

var dataArray = [];
data.split("--").forEach(function(x) {
    var arr = x.split("|");
    arr = arr.filter(function(e) {
        return e;
    });
    dataArray.push(arr);
});

这给了我一个多维数组

[Array(3), Array(3)]
    0: ["id: ticket/327364", "Subject: Beställning av inkoppling", "Due: Ej inställd"]
    1: ["id: ticket/327366", "Subject: Beställning av inkoppling", "Due: Ej inställd"]

这就是我被困住的地方,因为我想在“:”上拆分这些数组。因此,Object.Due将给出截止日期和Object.Subject给我主题等。此外,它并不总是id,Subject和Due。有时可能会有更少或更多的条目。

我试过这个

var result = {};
dataArray.forEach(function(x) {
    x.forEach(function(y) {
       var newArr = y.split(":");
       newArr[1] && (result[newArr[0]] = newArr[1]);
    });
});

这给了我我想要的东西,它给了我一个像这样的对象。

{id: " ticket/327366", Subject: " TestTwo", Due: " 2018"}

但是,结果只包含最后一个数组的数据。这就像它覆盖了第一个。关于如何重新做这个的任何建议?此外,它感觉像是一个非常多的循环,但我只是在用一两天的时间讨论JS,所以我还没有找到一种不同的方法。

4 个答案:

答案 0 :(得分:2)

在第二个代码块中,您只构建一个对象:您需要一个数组,但result不是数组。将该对象声明移动到外部循环中,并在每次迭代结束时将该对象推送到最终数组。请参阅代码中我做出更改的注释:

var data = '||id: ticket/327364|Subject: TestSubject|Due: 2018||--||id: ticket/327366|Subject: TestTwo|Due: 2018|||';

var dataArray = [];
data.split("--").forEach(function(x) {
    var arr = x.split("|");
    arr = arr.filter(function(e) {
        return e;
    });
    dataArray.push(arr);
});

var resultArray = []; // <--- final array
dataArray.forEach(function(x) {
    var result = {}; // <--- one object per iteration
    x.forEach(function(y) {
       var newArr = y.split(":");
       newArr[1] && (result[newArr[0]] = newArr[1]);
    });
    resultArray.push(result); // <--- push it
});
console.log(resultArray);
.as-console-wrapper { max-height: 100% !important; top: 0; }

替代方案,函数式编程方式

这是另一种方法,它使用了几种ES6功能,例如扩展语法,箭头函数,Object.assign和计算属性语法:

const data = '||id: ticket/327364|Subject: TestSubject|Due: 2018||--||id: ticket/327366|Subject: TestTwo|Due: 2018|||';

const dataArray = data.split("--").map(x =>
    Object.assign(...
               x.split("|")
                .filter(e => e)
                .map(s => s.split(':'))
                .map(([key, value]) => ({ [key]: value.trim() }))
    )
);

console.log(dataArray);
.as-console-wrapper { max-height: 100% !important; top: 0; }

答案 1 :(得分:1)

嗯,这是因为,据我所知,您每次都在结果变量中创建一个单独的对象,因此您每次都会在循环中覆盖结果。我认为你应该将结果对象插入到一个结果数组中并迭代通过它在循环的每个cicle中插入带有.push()的数组中的结果。

不知道这对你有意义。

答案 2 :(得分:1)

这是一种避免不必要引用的不同方法:

const input = '||id: ticket/327364|Subject: TestSubject|Due: 2018||--||id: ticket/327366|Subject: TestTwo|Due: 2018|||';

const result = input
  .split('--')
  .map(subArray => {
    const resultObject = {};
    const filtered = subArray
      .split('|')
      .filter(item => item.length > 0);

    for (let element of filtered) {
      const [key, value] = element.split(':');
      resultObject[key] = value.trim();
    }
    return resultObject;
  });

console.log(result);

在您的版本中,您将相应键的值设置为新值,因为对象具有重复键,它们被最新的键覆盖。

答案 3 :(得分:1)

每个dataArray条目需要一个结果,而不是整体结果。因此,将对象创建放在正确的位置,并将它们收集在一个数组中:

var results = dataArray.map(function(x) {
    var result = {};
    for (var y of x) {
       var newArr = y.split(":");
       if (newArr[1]) result[newArr[0]] = newArr[1];
    }
    return result;
});