【译】使用 JavaScript 创建图

网友投稿 259 2022-08-31

【译】使用 JavaScript 创建图

图是由具有边的节点集合组成的数据结构。图可以是有向的或者是无向的。

有向图包含功能类似于单行道的边。边缘从一个节点流向另一个节点。

比如,你可能有一个(关于)人物和电影的图表,其中每个人可以有多个喜欢的电影,但是电影没有喜欢的人。

无向图包含双向流动的边缘,类似于双向道路,两个方向都有交通。

比如,你可能有一个宠物图表,其中每只宠物都有一个所有者,每个所有者都有一只宠物。

备注:(下面)双向箭头代表一条边,但是为了显而易见,我绘制了两条箭头。

**图(graph)**中没有明确的信息层次结构。

方法

我们将创建一个(关于)人和冰淇凌口味的图表。这将是一个有向图,因为人们可以喜欢某些口味,但是味道可不喜欢人。

我们将创建三个类:

​​PersonNode​​​​IceCreamFlavorNode​​​​Graph​​

PersonNode

​​PersonNode​​类将接受一个参数:一个人的名字。这将作为其标识符。

​​PersonNode​​构造函数将包含两个属性:

​​name​​:唯一标识符​​favoriteFlavors​​:关于IceCreamFlavorNodes的数组

另外,​​PersonNode​​​类包含一个方法:​​addFlavor​​​。这将传入一个参数,一个​​IceCreamFlavorNode​​​对象,并将其添加到数组​​favoriteFlavors​​中。

类的定义如下所示:

class PersonNode { constructor(name) { this.name = name; this.favoriteFlavors = []; } addFlavor(flavor) { this.favoriteFlavors.push(flavor); }}

IceCreamFlavorNode

​​IceCreamFlavorNode​​类将传入一个参数:冰淇凌口味。这将作为其标识符。

这个类不需要包含任何方法,因为这是一个无向图,数据是从​​person​​​流向​​flavors​​,但是不会回流。

这个类的定义如下:

class IceCreamFlavorNode { constructor(flavor) { this.flavor = flavor; }}

Graph

​​Graph​​类不接受任何参数,但是其构造函数将包含三个属性:

​​peopleNodes​​:人物节点数组。​​iceCreamFlavorNodes​​:冰淇凌口味节点数组。​​edges​​​:包含​​PersonNodes​​​和​​IceCreamFlavorNodes​​之间的边缘数组。

​​Graph​​类将包含六个方法:

​​addPersonNode(name)​​​:接受一个参数,一个人的名字,创建一个具有此名字的​​PersonNode​​​对象,并将其推送到​​peopleNodes​​数组。​​addIceCreamFlavorNode(flavor)​​​:接受一个参数,一个冰淇凌口味,创建一个具有这种口味的​​IceCreamFlavorNode​​​对象,并将其推送到​​iceCreamFlavorNodes​​数组中。​​getPerson(name)​​:接受一个参数,一个人名字,并返回该人的节点。​​getFlavor(flavor)​​:接受一个参数,一个冰淇凌口味,并返回该口味的节点。​​addEdge(personName, flavorName)​​​:接受两个参数,一个人的名称和一个冰淇凌口味,检索两个节点,将​​flavor​​​添加到人的​​favoriteFlavors​​​数组,并将边推送到​​edge​​数组。​​print()​​​:简单打印出​​peopleNodes​​数组中的每个人,以及他们最喜欢的冰淇凌口味。

类的定义如下所示:

class Graph { constructor() { this.peopleNodes = []; this.iceCreamFlavorNodes = []; this.edges = []; } addPersonNode(name) { this.peopleNodes.push(new PersonNode(name)); } addIceCreamFlavorNode(flavor) { this.iceCreamFlavorNodes.push(new IceCreamFlavorNode(flavor)); } getPerson(name) { return this.peopleNodes.find(person person.name === name); } getFlavor(flavor) { return this.iceCreamFlavorNodes.find(flavor flavor === flavor); } addEdge(personName, flavorName) { const person = this.getPerson(personName); const flavor = this.getFlavor(flavorName); person.addFlavor(flavor); this.edges.push(`${personName} - ${flavorName}`); } print() { return this.peopleNodes.map(({ name, favoriteFlavors }) => { return `${name} => ${favoriteFlavors.map(flavor => `${flavor.flavor},`).join(' ')}`; }).join('\n') }}

虚拟数据

现在,我们有了三个类,我们可以添加一些数据并测试它们:

const graph = new Graph(true);graph.addPersonNode('Emma');graph.addPersonNode('Kai');graph.addPersonNode('Sarah');graph.addPersonNode('Maranda');graph.addIceCreamFlavorNode('Chocolate Chip');graph.addIceCreamFlavorNode('Strawberry');graph.addIceCreamFlavorNode('Cookie Dough');graph.addIceCreamFlavorNode('Vanilla');graph.addIceCreamFlavorNode('Pistachio');graph.addEdge('Emma', 'Chocolate Chip');graph.addEdge('Emma', 'Cookie Dough');graph.addEdge('Emma', 'Vanilla');graph.addEdge('Kai', 'Vanilla');graph.addEdge('Kai', 'Strawberry');graph.addEdge('Kai', 'Cookie Dough');graph.addEdge('Kai', 'Chocolate Chip');graph.addEdge('Kai', 'Pistachio');graph.addEdge('Maranda', 'Vanilla');graph.addEdge('Maranda', 'Cookie Dough');graph.addEdge('Sarah', 'Strawberry');console.log(graph.print());

下面是我们有向图看起来类似(的样子):

如果你想看完整的代码,到我的​​CodePen​​上查看。

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:介绍几个有趣的网站(十四)
下一篇:快速释放爆款营销力,五度营销“效果营销”玩出新高度!
相关文章

 发表评论

暂时没有评论,来抢沙发吧~