展平JSON数据

时间:2019-06-25 12:07:14

标签: javascript json tabulator

我正在尝试使用制表器创建票证列表,数据是通过AJAX url从票证系统作为JSON导入的,如下所示。

{
    "results": [
        {
            "cc_emails": [
                "ram@freshdesk.com",
                "diana@freshdesk.com"
            ],
            "fwd_emails": [],
            "reply_cc_emails": [
                "ram@freshdesk.com",
                "diana@freshdesk.com"
            ],
            "ticket_cc_emails": [
                "ram@freshdesk.com",
                "diana@freshdesk.com"
            ],
            "fr_escalated": false,
            "spam": false,
            "email_config_id": null,
            "group_id": 35000204315,
            "priority": 1,
            "requester_id": 35020281588,
            "responder_id": 35004154466,
            "source": 2,
            "company_id": null,
            "status": 2,
            "subject": "Support Needed...",
            "association_type": null,
            "to_emails": null,
            "product_id": null,
            "id": 188261,
            "type": null,
            "due_by": "2019-09-17T15:12:07Z",
            "fr_due_by": "2019-07-01T15:12:07Z",
            "is_escalated": false,
            "description": "<div>Details about the issue...</div>",
            "description_text": "Details about the issue...",
            "custom_fields": {
                "cf_category": null,
                "cf_firstname": null,
                "cf_surname": null,
                "cf_user_trainging": null,
                "cf_email_address": null,
                "cf_office_365": null,
                "cf_start_date": null,
                "cf_permission_level": null,
                "cf_hardware_type": null,
                "cf_additional_information_specsoftware_etc": null,
                "cf_vpn_access_required": false,
                "cf_securitydistribution_group_membership": null,
                "cf_mapped_network_driveslogin_script": null,
                "cf_printers": null,
                "cf_phone_extension": null,
                "cf_ddi": null,
                "cf_phone_group_membership": null,
                "cf_user_who_requires_the_equipment": null,
                "cf_requirment_date": null,
                "cf_correctclosureused": null,
                "cf_location": "A1"
            },
            "created_at": "2019-06-24T15:11:47Z",
            "updated_at": "2019-06-24T15:59:00Z",
            "associated_tickets_count": null,
            "tags": []
        }
    ],
    "total": 1
}

问题是“ custom_fields”是主JSON对象内部的JSON对象,是否有办法将这些数据展平并在制表器中显示为全部一行?任何帮助表示赞赏吗?

我在制表器中的当前结果是它为custom_fields列返回[object Object]。我希望能够看到该行中的每个custom_fields。

3 个答案:

答案 0 :(得分:0)

如果您使用的是es6 +,则可以通过在对象分解和对象传播中使用rest来轻松实现此目的。

const input =  {
    "results": [
        {
            "custom_fields": {...},
            ...
        }
    ],
    "total": 1
}

const expanded = input.results.map(result => {
   const { custom_fields, ...rest } = result;
   return { ...rest, ...custom_fields };
})

答案 1 :(得分:0)

这里有一个稍微不同的解决方案,它依赖函数生成器遍历原始对象,从而有可能最终检测到某些重复的键。

当然,可以通过添加更多检查(例如,是否要遍历主对象内的所有对象,等等)来更改此示例。

当前示例处理:

  • 通过排除基元和数组来遍历原始对象。
  • 提供了一个flattenObject方法,该方法接受一个对象作为参数,并提供一个回调作为最终的第二个参数,当遇到重复的键时将引发该参数。在这种情况下,默认行为是将“下一个”嵌套值作为新值。如果在回调中返回false,则保留当前值。回调将提供键和新值的值。

因此,简而言之,获得所需结果的“真实”代码是这样的:

// Case usage:
// Map the existing values.
input.results = input.results.map(i => flattenObject(i, (duplicatedKeyValuePair) => {
  return false; // <-- keep the existing value if a duplicate is matched.
}));
console.log(input.results)

当然,要使所需的属性变平,它会稍微复杂一些,但我想给它提供更具弹性的味道。

const input = {
    "results": [
        {
            "cc_emails": [
                "ram@freshdesk.com",
                "diana@freshdesk.com"
            ],
            "fwd_emails": [],
            "reply_cc_emails": [
                "ram@freshdesk.com",
                "diana@freshdesk.com"
            ],
            "ticket_cc_emails": [
                "ram@freshdesk.com",
                "diana@freshdesk.com"
            ],
            "fr_escalated": false,
            "spam": false,
            "email_config_id": null,
            "group_id": 35000204315,
            "priority": 1,
            "requester_id": 35020281588,
            "responder_id": 35004154466,
            "source": 2,
            "company_id": null,
            "status": 2,
            "subject": "Support Needed...",
            "association_type": null,
            "to_emails": null,
            "product_id": null,
            "id": 188261,
            "type": null,
            "due_by": "2019-09-17T15:12:07Z",
            "fr_due_by": "2019-07-01T15:12:07Z",
            "is_escalated": false,
            "description": "<div>Details about the issue...</div>",
            "description_text": "Details about the issue...",
            "test_duplicated_key": "hello! I should keep this!",
            "custom_fields": {
                "cf_category": null,
                "cf_firstname": null,
                "cf_surname": null,
                "cf_user_trainging": null,
                "cf_email_address": null,
                "cf_office_365": null,
                "cf_start_date": null,
                "cf_permission_level": null,
                "cf_hardware_type": null,
                "cf_additional_information_specsoftware_etc": null,
                "cf_vpn_access_required": false,
                "cf_securitydistribution_group_membership": null,
                "cf_mapped_network_driveslogin_script": null,
                "cf_printers": null,
                "cf_phone_extension": null,
                "cf_ddi": null,
                "cf_phone_group_membership": null,
                "cf_user_who_requires_the_equipment": null,
                "cf_requirment_date": null,
                "cf_correctclosureused": null,
                "cf_location": "A1",
                "test_duplicated_key": "You should not see that."
            },
            "created_at": "2019-06-24T15:11:47Z",
            "updated_at": "2019-06-24T15:59:00Z",
            "associated_tickets_count": null,
            "tags": []
        }
    ],
    "total": 1
}

/**
  Traverse every property of the desired object, by returning the currently key-value pair looped. If the value is an object, it keeps traversing.
*/
function* traverseObject(obj) {
  for ([key, value] of Object.entries(obj)) {
    if (value && typeof(value) === 'object' && !Array.isArray(value)) {
      yield* traverseObject(obj[key]);
    }
    else yield {key: key, value: value};
  }
}

/**
  Flattens the object by traversing every object inside it.
*/
function flattenObject(obj, onDuplicatedKey) {
  let res = {};
  for (keyValuePair of traverseObject(obj)) {
    let add = true;
    if (res.hasOwnProperty(keyValuePair.key)) {
      add = onDuplicatedKey ? onDuplicatedKey.call(onDuplicatedKey, keyValuePair) : true; // default behavior: override with nested propeties.
    }
    if (add) res[keyValuePair.key] = keyValuePair.value;
  }
  return res;
}

/*
Sample usage.
const flattened = flattenObject(input.results[0], (record) => {
  console.log('detected key value pair duplicate. Key:', record.key, ' value: ', record.value);
  // true will override the value, false will not override the value.
  return false;
});
*/
//console.log(flattened);

// Case usage:
// Map the existing values.
input.results = input.results.map(i => flattenObject(i, (duplicatedKeyValuePair) => {
  return false; // <-- keep the existing value if a duplicate is matched.
}));
console.log(input.results);

请注意,上述情况只是一个例子,我没有花太多时间测试每种属性类型,因此(当然)可以对其进行检查,并且可以提高代码质量和性能。这只是一个示例,展示了一种依赖于不同运算符和逻辑的不同方法。

作为最后一点,我认为您可以通过制表符以某种方式处理此问题,尽管我不确定您是否可以从单个属性中呈现多个列,这使我相信更改原始对象可能是理想的解决方案。

答案 2 :(得分:0)

处理嵌套数据

如果您在字段名称中使用点表示法,则无需展平对象,Tabulator可以处理列的嵌套数据:

var table = new Tabulator("#example-table", {
    columns:[
        {title:"Category", field:"custom_fields.cf_category"},  //link column to nested field
    ],
});

有关嵌套数据处理的完整详细信息,请参见Columns Documentation

列分组

如果您愿意,还可以使用列分组来显示字段是另一个属性的子集,例如,我们可以像往常一样定义顶级列,然后添加列组来保存自定义列

var table = new Tabulator("#example-table", {
    columns:[
        {title:"Subject", field:"subject"},  //standard column
        {title:"Priorty", field:"priority"}, //standard column
        {title:"Custom", columns:[ //column group to hold columns in custom_fields property
            {title:"Category", field:"custom_fields.cf_category"}, 
            {title:"First Name", field:"custom_fields.cf_firstname"}, 
        ]},
    ],
});

详细信息可以在Column Grouping Documentation

中找到