将对象数组转换为矩阵

说在前面

😀平时我们开发的时候基本都是用的json格式来进行数据处理,但是大家应该都遇到过需要将数据导出表格的场景吧,这时候我们就需要将对象数组转为数组矩阵📃。

需求

编写一个函数,将对象数组 arr 转换为矩阵 m 。

arr 是一个由对象组成的数组或一个数组。数组中的每个项都可以包含深层嵌套的子数组和子对象。它还可以包含数字、字符串、布尔值和空值。

矩阵 m 的第一行应该是列名。如果没有嵌套,列名是对象中的唯一键。如果存在嵌套,列名是对象中相应路径,以点号 "." 分隔。

剩余的每一行对应 arr 中的一个对象。矩阵中的每个值对应对象中的一个值。如果给定对象在给定列中没有值,则应该包含空字符串 "" 。

矩阵中的列应按 字典序升序 排列。

示例

示例 1
输入:
arr = [
  {"b": 1, "a": 2},
  {"b": 3, "a": 4}
]
输出:
[
  ["a", "b"],
  [2, 1],
  [4, 3]
]

解释:
两个对象中有两个唯一的列名:"a"和"b"。 
"a"对应[2, 4]。 
"b"对应[1, 3]。
示例 2
输入:
arr = [
  {"a": 1, "b": 2},
  {"c": 3, "d": 4},
  {}
]
输出:
[
  ["a", "b", "c", "d"],
  [1, 2, "", ""],
  ["", "", 3, 4],
  ["", "", "", ""]
]

解释:
有四个唯一的列名:"a"、"b"、"c"、"d"。 
 第一个对象具有与"a"和"b"关联的值。 
第二个对象具有与"c"和"d"关联的值。 
第三个对象没有键,因此只是一行空字符串。
示例 3
arr = [
  {"a": {"b": 1, "c": 2}},
  {"a": {"b": 3, "d": 4}}
]
输出:
[
  ["a.b", "a.c", "a.d"],
  [1, 2, ""],
  [3, "", 4]
]

解释:
在这个例子中,对象是嵌套的。键表示每个值的完整路径,路径之间用句点分隔。 
有三个路径:"a.b"、"a.c"、"a.d"。
示例4
输入:
arr = [
  [{"a": null}],
  [{"b": true}],
  [{"c": "x"}]
]
输出: 
[
  ["0.a", "0.b", "0.c"],
  [null, "", ""],
  ["", true, ""],
  ["", "", "x"]
]

解释:
数组也被视为具有索引为键的对象。 
每个数组只有一个元素,所以键是"0.a"、"0.b"和"0.c"。
示例5
输入:
arr = [
  {},
  {},
  {},
]
输出:
[
  [],
  [],
  [],
  []
]

解释:
没有键,所以每一行都是一个空数组。

代码实现

1. 函数功能概述

主要功能是将一个包含对象的数组(arr)转换为一个二维矩阵(二维数组)的形式,其中矩阵的第一行是从输入数组的所有对象中提取出的所有唯一的键名(经过排序),后续的每一行对应输入数组中的一个对象,该行中的每个元素是对应对象在特定键名位置上的值。如果某个对象在特定键名位置上没有对应的值,或者值是未定义的,或者该位置对应的仍然是一个对象(而非原始数据类型),则在矩阵中相应位置填充空字符串。

2. 函数参数
  • jsonToMatrix 函数接受一个参数:
    • arr:类型为 Array,即要进行转换处理的数组,数组中的元素应该是对象(或者包含对象的嵌套结构)。
3. 函数内部逻辑分析
  • 提取唯一键名集合(keySet
    • 首先定义一个空的 Set 对象 keySet,用于存储从输入数组 arr 中的所有对象里提取出的唯一键名。
    • 接着定义一个辅助函数 isObject,用于判断一个变量是否是对象(非 null 且类型为 object)。
    • 还定义了另一个辅助函数 getKeyName,它通过递归遍历一个对象的所有属性及其嵌套属性,将每个属性的路径名(以 . 连接各层级的键名)添加到 keySet 中。例如,如果有一个对象 {a: {b: 1}},那么会将 a.b 添加到 keySet 中。
    • 然后通过 arr.forEach((item) => getKeyName(item)); 遍历输入数组 arr 中的每个对象,调用 getKeyName 函数来提取所有对象的键名并添加到 keySet 中。
    • 最后将 keySet 转换为数组并进行排序,以便后续构建矩阵时键名能按照一定顺序排列。
let keySet = new Set();
const isObject = (x) => x !== null && typeof x === "object";
const getKeyName = (object, name = "") => {
   
   
  if 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JYeontu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值