json 使用嵌套Set的stringify Map

tsm1rwdh  于 2023-06-25  发布在  其他
关注(0)|答案(1)|浏览(128)

考虑下图:

class Node {
  constructor(value) {
    this.value = value;
    this.adjacents = new Set();
  }

  addAdjacent(node) {
    this.adjacents.add(node);
  }
}

class Graph {
  constructor(directed = false) {
    this.nodes = new Map();
    this.directed = directed;
  }

  addVertex(value) {
    const node = this.nodes.has(value);
    if (node) {
      return this.nodes.get(value);
    }

    const vertex = new Node(value);
    this.nodes.set(value, vertex);
    return vertex;
  }

  addEdge(src, dest) {
    let srcNode = this.nodes.get(src);
    if (!srcNode) {
      srcNode = this.addVertex(src);
    }

    let destNode = this.nodes.get(dest);
    if (!destNode) {
      destNode = this.addVertex(dest);
    }

    srcNode.addAdjacent(destNode);
    if (this.directed === false) {
      destNode.addAdjacent(srcNode);
    }
  }
}

const g1 = new Graph();
g1.addVertex("a");
g1.addVertex("b");
g1.addEdge("a", "c");

当I console.log时,图形对象g1。我得到以下输出:

Graph {
  nodes: Map(3) {
    'a' => Node { value: 'a', adjacents: [Set] },
    'b' => Node { value: 'b', adjacents: Set(0) {} },
    'c' => Node { value: 'c', adjacents: [Set] }
  },
  directed: false
}

如输出所示,我没有得到关于顶点边的信息。
我尝试将replacer传递给JSON.stringify,但它导致StackOverFlow错误。

console.log(
  JSON.stringify(
    Object.fromEntries(g1.nodes),
    (_key, value) =>
      value.adjacents instanceof Set ? [...value.adjacents] : value,
    2
  )
);

错误:

JSON.stringify(
       ^

RangeError: Maximum call stack size exceeded
    at JSON.stringify (<anonymous>)

如何以更友好的格式打印图表?

cngwdvgl

cngwdvgl1#

这里有两个问题。。

  1. MapSet都不会直接序列化为JSON
    1.您的数据结构是循环的,因此无法序列化;节点 a 与节点 c 相邻,节点 c 与节点 a 相邻。尝试将其序列化为平面结构将需要无限的存储空间。
    我建议在类中添加toJSON()方法来帮助序列化。在那里,不可序列化的数据结构可以转换为简单的结构,循环引用可以被打破。
    比如说,
class Node {
  constructor(value) {
    this.value = value;
    this.adjacents = new Set();
  }

  addAdjacent(node) {
    this.adjacents.add(node);
  }

  toJSON() {
    return {
      ...this,
      // plain array with scalar values
      adjacents: [...this.adjacents].map(({ value }) => value),
    };
  }
}

class Graph {
  constructor(directed = false) {
    this.nodes = new Map();
    this.directed = directed;
  }

  addVertex(value) {
    const node = this.nodes.has(value);
    if (node) {
      return this.nodes.get(value);
    }

    const vertex = new Node(value);
    this.nodes.set(value, vertex);
    return vertex;
  }

  addEdge(src, dest) {
    let srcNode = this.nodes.get(src);
    if (!srcNode) {
      srcNode = this.addVertex(src);
    }

    let destNode = this.nodes.get(dest);
    if (!destNode) {
      destNode = this.addVertex(dest);
    }

    srcNode.addAdjacent(destNode);
    if (this.directed === false) {
      destNode.addAdjacent(srcNode);
    }
  }

  toJSON() {
    return {
      ...this,
      // reduce the Map entries to a simple object
      nodes: Object.fromEntries(this.nodes),
    };
  }
}

const g1 = new Graph();
g1.addVertex("a");
g1.addVertex("b");
g1.addEdge("a", "c");

console.log(JSON.stringify(g1, null, 2));
.as-console-wrapper { max-height: 100% !important; }

相关问题