将键/值对的行序列化为JSON对象

时间:2013-08-16 05:02:04

标签: json data-structures opengraph facebook-opengraph open-graph-protocol

我需要帮助转换这个数据表:

[
    {property:"key", content:"1"},
    {property:"key", content:"2"},
    {property:"key2", content:"3"},
    {property:"key2:subkey", content:"4"},
    {property:"key2:someother:key", content:"5"},
    {property:"foo", content:"6"},
    {property:"foo", content:"7"},
    {property:"foo:bar", content:"8"}
]

进入具有以下结构的JSON对象:

{
  key: ["1", "2"],
  key2: {
    '': "3"
    subkey: "4"
    someother: {
      key: "5"
    }
  },
  foo: [
    "6",
    {
      '': "7"
      bar: "8"
    }
  ]
}

以下是规则。注意:所有规则都适用于JSON对象中的任何级别(json.levelOne,json.level.two,json.level.three.even等)

  1. 对于每个row.property"a:b:c"应转换为json.a.b.c = row.content
  2. row.property = "x"json.x !== undefined然后json.x = [json.x, row.content]
  3. 每当json.x === "string"row.property = "x:y"然后json.x = {'': json.x, y: row.content}
  4. 每当Array.isArray(json.x) && json.x[json.x.length-1] === "string"row.property = "x:y"然后json.x[json.x.length-1] = {'': json.x[json.x.length-1], y: row.content}
  5. 希望这可以让您了解将数据转换为此JSON对象格式需要执行的操作的标准。

    为什么?

    我正在尝试使用Open Graph元数据并将其序列化为JSON对象。我觉得上面的格式最能反映Open Graph元数据结构。我需要帮助编写这个算法。这是我正在开发的一个开源Node.js项目。

    感谢所有帮助。谢谢!

    修改

    因此解析器还有一些问题。在某些情况下,数组会出现在叶节点上。

    以下是GitHub上的项目:https://github.com/samholmes/node-open-graph随意分叉,构建一个更好的解析,并向我发送拉取请求。

1 个答案:

答案 0 :(得分:1)

根据我们关于IRC的讨论更新

var data = [
    {property:"key", content:"1"},
    {property:"key", content:"2"},
    {property:"key2", content:"3"},
    {property:"key2:subkey", content:"4"},
    {property:"key2:someother:key", content:"5"},
    {property:"foo", content:"6"},
    {property:"foo", content:"7"},
    {property:"foo:bar", content:"8"},
    {property:"foo:baz", content:"9"}
];

var transformed = {};

data.forEach(function (item) {
    var key, tmp,
        ptr = transformed,
        keys = item.property.split(':');

    // we want to leave one key to assign to so we always use references
    // as long as there's one key left, we're dealing with a sub-node and not a value

    while (keys.length > 1) {
        key = keys.shift();

        if (Array.isArray(ptr[key])) {
            // the last index of ptr[key] should become
            // the object we are examining.
            tmp = ptr[key].length-1;
            ptr = ptr[key];
            key = tmp;
        }

        if (typeof ptr[key] === 'string') {
            // if it's a string, convert it
            ptr[key] = { '': ptr[key] };
        } else if (ptr[key] === undefined) {
            // create a new key
            ptr[key] = {};
        }

        // move our pointer to the next subnode
        ptr = ptr[key];
    }

    // deal with the last key
    key = keys.shift();

    if (ptr[key] === undefined) {
        ptr[key] = item.content;
    } else if (Array.isArray(ptr[key])) {
        ptr[key].push(item.content);
    } else {
        ptr[key] = [ ptr[key], item.content ];
    }
});
console.log(transformed);

输出:

{
    key: ['1', '2'],
    key2: {
        '': '3',
        subkey: '4',
        someother: {
            key: '5'
        }
    },
    foo: ['6', {
        '': '7',
        bar: '8'
        baz: '9'
    }]
}