问题
需要这两个格式的数据,能够互相转换。
let obj = {
  a: 123,
  b: { a: 456, b: 789, c: { d: 111, e: 222 } },
  f: 11,
};
let arr = [
  { name: 'a', value: 123 },
  {
    name: 'b',
    value: undefined,
    children: [
      { name: 'a', value: 456 },
      { name: 'b', value: 789 },
      {
        name: 'c',
        value: undefined,
        children: [
          { name: 'd', value: 111 },
          { name: 'e', value: 222 },
        ],
      },
    ],
  },
  { name: 'f', value: 111 },
];
注意,对象名称为 name,对象的值不一定是 value,对象的值遇见 children 的时候,是个对象。
解决问题
我用的是循环递归,因为我太菜了
群里说的有 BFS 什么的,我知道这东西也大概用过,但说来惭愧,不会。
这个循环递归的方法有个大佬说还会爆栈,内存溢出。
// 数组转对象
function arrayToObject(params) {
  let obj = {};
  for (let index = 0; index < params.length; index++) {
    const element = params[index];
    const { name, value } = element;
    if ('children' in element) {
      obj[name] = arrayToObject(element.children);
    } else {
      obj[name] = value;
    }
  }
  return obj;
}
// 对象转数组
function ObjectToArray(params) {
  let array = [];
  for (const key in params) {
    if (Object.hasOwnProperty.call(params, key)) {
      const element = params[key];
      if (Object.prototype.toString.call(element) === '[object Object]') {
        array.push({ name: key, value: undefined, children: ObjectToArray(element) });
      } else {
        array.push({ name: key, value: element });
      }
    }
  }
  return array;
}
console.log(arrayToObject(arr));
console.log(ObjectToArray(obj));
求更好的解法
目前没有求到更好的解法,我先把解法和代码贴出来。
- 2021 年 5 月 17 日补充群友德巨 Kio 的回答
const o2a = (o) =>
  Object
    .entries(o)
    .map(([name, value]) =>
      typeof value !== 'object'
        ? { name, value }
        : { name, value: undefined, children: o2a(value) }
    );
const a2o = (a) =>
  a.reduce(
    (o, i) => ({ ...o, [i['name']]: i['value'] ?? a2o(i['children']) }),
    {}
  );