Skip to content

JS Tree 树状数据 Object Array 互转

Published: at 10:19 AMSuggest Changes

问题

需要这两个格式的数据,能够互相转换。

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));

求更好的解法

目前没有求到更好的解法,我先把解法和代码贴出来。

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']) }),
    {}
  );

Previous Post
Webpack 引入 SVG 文件
Next Post
优雅的 JavaScript 对象值判断和重置