【问题标题】:Format array of objects with different keys into table data将具有不同键的对象数组格式化为表数据
【发布时间】:2021-03-05 14:09:20
【问题描述】:

我正在尝试确定将对象数组映射到可用于呈现表格的数据的最简单方法。例如:

数据:

const data = [{
  name: "foo",
  phone: "123456",
  email: "foo@bar.com"
},
{
  name: "bar",
  address: "123 Main",
  country: "USA"
}];

表:

+------+--------+-------------+----------+-----------+
| name | phone  |    email    |  address |  country  |
+------+--------+-------------+----------+-----------+
| foo  | 123456 | foo@bar.com |          |           |
| bar  |        |             | 123 Main |    USA    |
+------+--------+-------------+----------+-----------+

如您所见,对象共享名称键,但在其他方面完全不同。此数据中的所有键和值都是动态的,因此它们可以是任何东西。

我发现从所有对象中获取所有唯一键的最佳方法是name, phone, email, address, country,然后再次循环遍历每个对象,用它没有的属性填充条目。像这样:

const formatData = (data) => {
  let keys = new Set([]);
  for (const entry of data) {
    keys = new Set([...keys, ...Object.keys(entry)])
  }
  const columns = Array.from(keys);
  const rows = [];

  for (const entry of data) {
    const row = [];
    for (const col of columns) {
      row.push(entry[col])
    }
    rows.push(row);
  }
  return {
    columns,
    rows
  }
}

这将返回格式如下的数据:

{
  columns: ["name", "phone", "email", "address", "country"],
  rows: [["foo", "123456", "foo@bar.com", undefined, undefined], ["bar", undefined, undefined, "123 Main", "USA"]]
}

从那里开始,当我渲染我的表格时,我可以遍历列并为每个列渲染一个,然后循环行,每个项目都是 a,每个嵌套数组都是 a。

这很好用,但我觉得我的算法效率不高或不可读。有没有更好的方法将数据转换为这种格式。我也在使用 lodash,所以 lodash 函数也可以工作。

【问题讨论】:

    标签: javascript object html-table format lodash


    【解决方案1】:

    您可以通过使用Array.flatMap() 来创建列,并使用 lodash 的_.at()Array.map() 来获取行的数据,从而使代码更具可读性(我希望 :)):

    const formatData = data => {
      const columns = Array.from(new Set(data.flatMap(Object.keys)));
      
      const rows = data.map(row => _.at(row, columns));
    
      return {
        columns,
        rows
      }
    }
    
    const data = [{"name":"foo","phone":"123456","email":"foo@bar.com"},{"name":"bar","address":"123 Main","country":"USA"}];
    
    const result = formatData(data);
    
    console.log(result);
    <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js" integrity="sha512-90vH1Z83AJY9DmlWa8WkjkV79yfS2n2Oxhsi2dZbIv0nC4E6m5AbH8Nh156kkM7JePmqD6tcZsfad1ueoaovww==" crossorigin="anonymous"></script>

    获取列的另一种选择是合并所有对象,然后获取键:

    const formatData = data => {
      const columns = Object.keys(Object.assign({}, ...data));
      
      const rows = data.map(row => _.at(row, columns));
    
      return {
        columns,
        rows
      }
    }
    
    const data = [{"name":"foo","phone":"123456","email":"foo@bar.com"},{"name":"bar","address":"123 Main","country":"USA"}];
    
    const result = formatData(data);
    
    console.log(result);
    <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js" integrity="sha512-90vH1Z83AJY9DmlWa8WkjkV79yfS2n2Oxhsi2dZbIv0nC4E6m5AbH8Nh156kkM7JePmqD6tcZsfad1ueoaovww==" crossorigin="anonymous"></script>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-17
      相关资源
      最近更新 更多