Skip to content

JS 遍历对象所有 key 并转成数组

Published: at 01:43 PMSuggest Changes

递归一个对象,拿到里面的 key,并且按层次输出到数组中

// 输入
let input = {
  a: {
    b: '123',
    c: {
      d: 456,
    },
  },
  b: {
    e: 789,
  },
  f: 222,
};

// 输出
let output = ['a.b', 'a.c.d', 'b.e', 'f'];

解决方法

一点也不高明的递归方法

function deepTree(tree) {
  let arr = [];
  for (const key in tree) {
    if (tree.hasOwnProperty.call(tree, key)) {
      const element = tree[key];
      if (Object.prototype.toString.call(element) == '[object Object]') {
        deepTree(element).forEach((element) => {
          arr.push(`${key}.${element}`);
        });
      } else {
        arr.push(`${key}`);
      }
    }
  }
  return arr;
}

console.log(`deepTree(input)`, deepTree(input))

来自德巨的分享

群友分享了广度优先遍历和深度优先遍历

let input = {
  a: {
    b: "123",
    c: {
      d: 456,
    },
  },
  b: {
    e: 789,
  },
  f: 222,
};

// 后面的 Flat 方法很有意思
const recursive = (tree, domain) =>
  Object.entries(tree)
    .map(([key, value]) => [value, domain ? `${domain}.${key}` : key])
    .map(([value, subDomain]) =>
      typeof value === "object" ? recursive(value, subDomain) : subDomain
    )
    .flat();

// 深度优先
function depthFirst(tree) {
  const stack = [[tree, ""]];
  const res = [];
  while (stack.length) {
    const [crt, crtPath] = stack.pop();
    if (typeof crt === "object") {
      const entries = Object.entries(crt);
      let i = entries.length;
      while (i--) {
        const [key, value] = entries[i];
        const path = crtPath ? `${crtPath}.${key}` : key;
        stack.push([value, path]);
      }
    } else {
      res.push(crtPath);
    }
  }
  return res;
}

// 广度优先
function widthFirst(tree) {
  const queue = [[tree, ""]];
  const res = [];
  while (queue.length) {
    const [crt, crtPath] = queue.shift();
    if (typeof crt === "object") {
      const entries = Object.entries(crt);
      const last = entries.length - 1;
      let i = -1;
      while (i++ < last) {
        const [key, value] = entries[i];
        const path = crtPath ? `${crtPath}.${key}` : key;
        queue.push([value, path]);
      }
    } else {
      res.push(crtPath);
    }
  }
  return res;
}

console.log(recursive(input));
console.log(depthFirst(input));
console.log(widthFirst(input));

广度优先遍历和深度优先遍历是啥我又忘了,得在复习一下


Previous Post
JS Array 和 Set 相互转换
Next Post
NodeJS 递归读取文件夹内容