{"id":232255,"date":"2023-01-13T20:12:00","date_gmt":"2023-01-13T17:12:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=232255"},"modified":"2022-11-10T08:19:50","modified_gmt":"2022-11-10T05:19:50","slug":"comment-creer-une-carte-bidirectionnelle-en-javascript","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/fr\/comment-creer-une-carte-bidirectionnelle-en-javascript\/","title":{"rendered":"Comment cr\u00e9er une carte bidirectionnelle en JavaScript"},"content":{"rendered":"\n<p>Une carte bidirectionnelle est un mod\u00e8le de l&rsquo;informatique o\u00f9 les paires cl\u00e9-valeur ont une relation bijective 1-1 entre les cl\u00e9s et les valeurs. Cela nous permet non seulement d&rsquo;interroger par cl\u00e9 et d&rsquo;obtenir une valeur, mais \u00e9galement d&rsquo;interroger par valeur et d&rsquo;obtenir la cl\u00e9. Voyons comment impl\u00e9menter une carte bidirectionnelle en JavaScript et rendons-la plus tard s\u00e9curis\u00e9e dans TypeScript<\/p>\n<h2>L&rsquo;informatique et les math\u00e9matiques derri\u00e8re<\/h2>\n<p>Prenons une d\u00e9finition de base d&rsquo;une carte bidirectionnelle\u00a0:<\/p>\n<blockquote>\n<p>En informatique, une <strong>carte bidirectionnelle<\/strong> est une structure de donn\u00e9es associative dans laquelle les paires cl\u00e9-valeur forment une correspondance biunivoque. Ainsi, la relation binaire est fonctionnelle dans chaque direction: chaque valeur peut \u00e9galement \u00eatre associ\u00e9e \u00e0 une cl\u00e9 unique.<\/p>\n<\/blockquote>\n<p><a href=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-157501-61e6b9e14822e.png\" data-rel=\"lightbox\" ><img decoding=\"async\" class=\"SDStudio-light-box-enable SDStudio-editor-tools-md-imp\" src=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-157501-61e6b9e14822e.png\" alt=\"Comment cr\u00e9er une carte bidirectionnelle en JavaScript\" ><\/a><\/p>\n<p>Cr\u00e9dit: <a href=\"https:\/\/en.wikipedia.org\/wiki\/Bidirectional_map\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Carte bidirectionnelle<\/a><\/p>\n<p>La carte bidirectionnelle de l&rsquo;informatique a ses racines dans une fonction math\u00e9matique appel\u00e9e bijection. La relation entre les composants d&rsquo;une paire avec chacun de ses composants dans diff\u00e9rents ensembles est une fonction bijective, \u00e9galement appel\u00e9e fonction inversible, qui est une fonction qui fonctionne dans les deux sens, associant exactement un \u00e9l\u00e9ment d&rsquo;un ensemble avec exactement un \u00e9l\u00e9ment de l&rsquo;autre ensemble :<\/p>\n<p><a href=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-157501-61e6b9e2a629e.png\" data-rel=\"lightbox\"><img decoding=\"async\" class=\"SDStudio-light-box-enable SDStudio-editor-tools-md-imp\" src=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-157501-61e6b9e2a629e.png\" alt=\"Comment cr\u00e9er une carte bidirectionnelle en JavaScript\" ><\/a><\/p>\n<p>Cr\u00e9dit: <a href=\"https:\/\/en.wikipedia.org\/wiki\/Bijection\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Bijection<\/a><\/p>\n<p>Dans cet esprit, nous pouvons savoir qu&rsquo;une fonction bijective pour les ensembles ci-dessus produira quelque chose comme\u00a0:<\/p>\n<p>f (1) = r\u00e9<br \/>\nf (C) = 3<\/p>\n<p>Une autre chose qui d\u00e9coule de la fonction bijective est que les ensembles auront exactement la m\u00eame longueur, sinon la bijection \u00e9chouerait.<\/p>\n<h2>Initialiser la carte bidirectionnelle<\/h2>\n<p>Nous allons mod\u00e9liser cela avec une classe <a href=\"https:\/\/startfunction.com\/category\/javascript\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">JavaScript<\/a> qui sera initialis\u00e9e avec un objet de paires cl\u00e9-valeur\u00a0:<\/p>\n<pre><code>const bimap = new BidirectionalMap({\n  a: 'A',\n  b: 'B',\n  c: 'C',\n})<\/code><\/pre>\n<p>En interne, nous allons cr\u00e9er deux listes. Une liste stockera la liste des paires de ce que nous appellerons une carte directe, o\u00f9 la cl\u00e9 correspond \u00e0 la valeur et sera une copie de l&rsquo;objet que nous avons utilis\u00e9 pour initialiser la carte bidirectionnelle. La deuxi\u00e8me liste sera ce que nous appellerons une carte invers\u00e9e et stockera une version de l&rsquo;objet utilis\u00e9 pour initialiser la carte bidirectionnelle o\u00f9 les paires cl\u00e9 &#8211; valeur ont \u00e9t\u00e9 invers\u00e9es et la &quot;valeur&quot; correspond maintenant \u00e0 la &quot;cl\u00e9&quot;:<\/p>\n<pre><code>class BidirectionalMap {\n  fwdMap = {}\n  revMap = {}\n\n  constructor(map) {\n      this.fwdMap = { ...map }\n      this.revMap = Object.keys(map).reduce(\n          (acc, cur) =&gt; ({\n              ...acc,\n              [map[cur]]: cur,\n          }),\n          {}) }\n}<\/code><\/pre>\n<p>Notez qu&rsquo;en raison de la nature de l&rsquo;objet qui initialise la carte bidirectionnelle, vous ne pouvez pas utiliser de nombre pour la cl\u00e9, mais vous pouvez toujours l&rsquo;utiliser comme valeur et vous pourrez plus tard interroger par celui-ci\u00a0:<\/p>\n<pre><code>const bimap = new BidirectionalMap({\n  a: 42,\n  b: 'B',\n  c: 'C',\n})<\/code><\/pre>\n<p>Une version plus robuste mais aussi plus complexe pourrait \u00eatre \u00e9crite avec le <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Global_Objects\/Map\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">type de donn\u00e9es Map<\/a> de JavaScript et autoriser les cl\u00e9s qui sont des nombres, des fonctions ou m\u00eame NaN.<\/p>\n<h2>Obtenir un \u00e9l\u00e9ment d&rsquo;une carte bidirectionnelle<\/h2>\n<p>Jusqu&rsquo;\u00e0 pr\u00e9sent, nous avons une structure de donn\u00e9es qui h\u00e9berge deux objets, l&rsquo;un d&rsquo;eux \u00e9tant un miroir de l&rsquo;autre en termes de cl\u00e9 &#8211; valeurs. Nous avons maintenant besoin d&rsquo;une m\u00e9thode pour en tirer quelque chose. Impl\u00e9mentons une <code>get()<\/code>fonction\u00a0:<\/p>\n<pre><code>  get( key) {\n      return this.fwdMap[key] || this.revMap[key]\n  }<\/code><\/pre>\n<p>C&rsquo;est tr\u00e8s simple: s&rsquo;il existe dans la carte vers l&rsquo;avant, nous le renvoyons, sinon nous le renvoyons depuis la carte invers\u00e9e. S&rsquo;il n&rsquo;en existe pas, <code>undefined<\/code>sera retourn\u00e9.<\/p>\n<p>Nous pouvons maintenant obtenir des \u00e9l\u00e9ments comme :<\/p>\n<pre><code>console.log( bimap.get('a')) console.log( bimap.get('A')) <\/code><\/pre>\n<h2>Ajouter un \u00e9l\u00e9ment \u00e0 une carte bidirectionnelle<\/h2>\n<p>Notre carte n&rsquo;a actuellement aucun moyen d&rsquo;ajouter plus d&rsquo;\u00e9l\u00e9ments, alors ajoutons une fonction pour ajouter de nouveaux \u00e9l\u00e9ments \u00e0 la carte\u00a0:<\/p>\n<pre><code>  add( pair) {\n    this.fwdMap[pair[0]] = pair[1]\n    this.revMap[pair[1]] = pair[0]\n  }<\/code><\/pre>\n<p>Cela recevra un tableau de deux \u00e9l\u00e9ments, que nous taperons plus tard comme un tuple avec <a href=\"https:\/\/startfunction.com\/tag\/typescript\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">TypeScript<\/a>, et les affectera comme cl\u00e9 &#8211; valeurs dans les deux sens aux objets correspondants.<\/p>\n<p>Et maintenant nous pouvons ajouter une paire et interroger cette nouvelle paire<\/p>\n<pre><code>bimap.add(['d', 'D'])\nconsole.log( bimap.get('D')) <\/code><\/pre>\n<h2>Une carte bidirectionnelle de type s\u00e9curis\u00e9 dans TypeScript<\/h2>\n<p>Pour am\u00e9liorer les choses et taper en toute s\u00e9curit\u00e9, nous pouvons r\u00e9\u00e9crire cela dans TypeScript et ajouter des concepts de typage comme un objet g\u00e9n\u00e9rique lors de l&rsquo;initialisation de la carte et un <a href=\"https:\/\/www.typescriptlang.org\/docs\/handbook\/basic-types.html#tuple\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">tuple<\/a> lors de l&rsquo;ajout d&rsquo;un nouvel \u00e9l\u00e9ment.<\/p>\n<pre><code>class BidirectionalMap {\n  fwdMap = {}\n  revMap = {}\n\n  constructor(map: { [key: string]: string }) {\n      this.fwdMap = { ...map }\n      this.revMap = Object.keys(map).reduce(\n          (acc, cur) =&gt; ({\n              ...acc,\n              [map[cur]]: cur,\n          }),\n          {}) }\n\n  get(key: string): string | undefined {\n      return this.fwdMap[key] || this.revMap[key]\n  }\n\n  add(pair: [string, string]) {\n    this.fwdMap[pair[0]] = pair[1]\n    this.revMap[pair[1]] = pair[0]\n  }\n}<\/code><\/pre>\n<p>Ce typage rend maintenant notre carte parfaitement s\u00fbre et garantit, dans ce cas, que nous utiliserons toujours des cha\u00eenes pour les cl\u00e9s et les valeurs.<\/p>\n<p><div id=\"PostUnique_PostSource\" style=\"padding-top: 50px\">Source d&rsquo;enregistrement:  <a target=\"_blank\" rel=\"noopener nofollow\" href=\"\/\/startfunction.com\" class=\"external external_icon\">startfunction.com<\/a><\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Vous pouvez interroger ces cartes par cl\u00e9 et obtenir sa valeur ou par valeur et obtenir sa cl\u00e9<\/p>\n","protected":false},"author":1,"featured_media":224548,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_wp_rev_ctl_limit":""},"categories":[893,717,728,748,841],"tags":[1167],"class_list":["post-232255","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-code-2","category-developpeur","category-javascript-3","category-open-source-projektmanagement-2","category-tutoriels","tag-affiai-fr"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/fr\/wp-json\/wp\/v2\/posts\/232255","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.mediadoma.com\/fr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wordpress.mediadoma.com\/fr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/fr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/fr\/wp-json\/wp\/v2\/comments?post=232255"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/fr\/wp-json\/wp\/v2\/posts\/232255\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/fr\/wp-json\/wp\/v2\/media\/224548"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/fr\/wp-json\/wp\/v2\/media?parent=232255"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/fr\/wp-json\/wp\/v2\/categories?post=232255"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/fr\/wp-json\/wp\/v2\/tags?post=232255"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}