{"id":231803,"date":"2023-01-13T20:49:00","date_gmt":"2023-01-13T17:49:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=231803"},"modified":"2022-11-10T05:16:32","modified_gmt":"2022-11-10T02:16:32","slug":"hur-man-skapar-en-dubbelriktad-karta-i-javascript","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/sv\/hur-man-skapar-en-dubbelriktad-karta-i-javascript\/","title":{"rendered":"Hur man skapar en dubbelriktad karta i JavaScript"},"content":{"rendered":"\n<p>En dubbelriktad karta \u00e4r en modell fr\u00e5n datavetenskap d\u00e4r nyckel-v\u00e4rdepar har ett bijektivt 1-1-f\u00f6rh\u00e5llande mellan nycklarna och v\u00e4rdena. Detta till\u00e5ter oss att inte bara fr\u00e5ga efter nyckel och f\u00e5 ett v\u00e4rde, utan ocks\u00e5 att fr\u00e5ga efter v\u00e4rdet och f\u00e5 nyckeln. L\u00e5t oss se hur man implementerar en dubbelriktad karta i JavaScript och l\u00e5t oss g\u00f6ra den senare typs\u00e4ker i TypeScript<\/p>\n<h2>Datavetenskapen och matematiken bakom<\/h2>\n<p>L\u00e5t oss ta en grundl\u00e4ggande definition av en dubbelriktad karta:<\/p>\n<blockquote>\n<p>Inom datavetenskap \u00e4r en <strong>dubbelriktad karta<\/strong> en associativ datastruktur d\u00e4r nyckel-v\u00e4rdeparen bildar en en-till-en-korrespondens. S\u00e5ledes \u00e4r den bin\u00e4ra relationen funktionell i varje riktning: varje v\u00e4rde kan ocks\u00e5 mappas till en unik nyckel.<\/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=\"Hur man skapar en dubbelriktad karta i JavaScript\" ><\/a><\/p>\n<p>Kredit: <a href=\"https:\/\/en.wikipedia.org\/wiki\/Bidirectional_map\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Dubbelriktad karta<\/a><\/p>\n<p>Den dubbelriktade kartan fr\u00e5n datavetenskap har sina r\u00f6tter i en matematisk funktion som kallas bijektion. Relationen mellan komponenterna i ett par med var och en av dess komponent i olika m\u00e4ngder \u00e4r en bijektiv funktion, \u00e4ven kallad en inverterbar funktion, vilket \u00e4r en funktion som fungerar p\u00e5 b\u00e5da s\u00e4tten, parar ihop exakt ett element fr\u00e5n en m\u00e4ngd med exakt ett element av det andra setet:<\/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=\"Hur man skapar en dubbelriktad karta i JavaScript\" ><\/a><\/p>\n<p>Kredit: <a href=\"https:\/\/en.wikipedia.org\/wiki\/Bijection\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Bijection<\/a><\/p>\n<p>Med detta i \u00e5tanke kan vi veta att en bijektiv funktion f\u00f6r upps\u00e4ttningarna ovan kommer att producera n\u00e5got som:<\/p>\n<p>f (1) = D<br \/>\nf (C) = 3<\/p>\n<p>En annan sak som uppst\u00e5r fr\u00e5n den bijektiva funktionen \u00e4r att m\u00e4ngderna kommer att ha exakt samma l\u00e4ngd, annars skulle bijektionen misslyckas.<\/p>\n<h2>Initiera den dubbelriktade kartan<\/h2>\n<p>Vi modellerar detta med en <a href=\"https:\/\/startfunction.com\/category\/javascript\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">JavaScript<\/a> -klass som kommer att initieras med ett objekt med nyckel-v\u00e4rdepar:<\/p>\n<pre><code>const bimap = new BidirectionalMap({\n  a: 'A',\n  b: 'B',\n  c: 'C',\n})<\/code><\/pre>\n<p>Internt skapar vi tv\u00e5 listor. En lista kommer att lagra listan med par av vad vi kallar en fram\u00e5tkarta, d\u00e4r nyckelkartor \u00e4r v\u00e4rdefulla och kommer att vara en kopia av objektet vi anv\u00e4nde f\u00f6r att initialisera den dubbelriktade kartan. Den andra listan kommer att vara vad vi kallar en omv\u00e4nd karta, och kommer att lagra en version av objektet som anv\u00e4nds f\u00f6r att initiera den dubbelriktade kartan d\u00e4r nyckel-v\u00e4rdeparen har v\u00e4nts och &quot;v\u00e4rdet&quot; nu mappas till &quot;nyckeln&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>Observera att p\u00e5 grund av arten av objektet som initierar den dubbelriktade kartan kan du inte anv\u00e4nda ett nummer f\u00f6r nyckeln men du kan fortfarande anv\u00e4nda det som ett v\u00e4rde och du kommer senare att kunna fr\u00e5ga efter det:<\/p>\n<pre><code>const bimap = new BidirectionalMap({\n  a: 42,\n  b: 'B',\n  c: 'C',\n})<\/code><\/pre>\n<p>En mer robust men ocks\u00e5 mer komplex version skulle kunna skrivas med <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Global_Objects\/Map\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">kartdatatypen<\/a> JavaScript och till\u00e5ta nycklar som \u00e4r siffror, funktioner eller till och med NaN.<\/p>\n<h2>F\u00e5 ett element fr\u00e5n en dubbelriktad karta<\/h2>\n<p>Fram till denna punkt har vi en datastruktur som \u00e4r v\u00e4rd f\u00f6r tv\u00e5 objekt, varav det ena \u00e4r en spegel av det andra n\u00e4r det g\u00e4ller nyckelv\u00e4rden. Vi beh\u00f6ver nu en metod f\u00f6r att f\u00e5 ut n\u00e5got av det. L\u00e5t oss implementera en <code>get()<\/code>funktion:<\/p>\n<pre><code>  get( key) {\n      return this.fwdMap[key] || this.revMap[key]\n  }<\/code><\/pre>\n<p>Det \u00e4r v\u00e4ldigt enkelt: om det finns i den fram\u00e5triktade kartan returnerar vi det, annars returnerar vi det fr\u00e5n den omv\u00e4nda kartan. Om ingen finns, <code>undefined<\/code>kommer den att returneras.<\/p>\n<p>Vi kan nu f\u00e5 n\u00e5gra element som:<\/p>\n<pre><code>console.log( bimap.get('a')) console.log( bimap.get('A')) <\/code><\/pre>\n<h2>L\u00e4gg till ett element till en dubbelriktad karta<\/h2>\n<p>V\u00e5r karta har f\u00f6r n\u00e4rvarande inte ett s\u00e4tt att l\u00e4gga till fler element s\u00e5 l\u00e5t oss l\u00e4gga till en funktion f\u00f6r att l\u00e4gga till nya element p\u00e5 kartan:<\/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>Detta kommer att ta emot en upps\u00e4ttning av tv\u00e5 element, som vi senare kommer att skriva som en tuppel med <a href=\"https:\/\/startfunction.com\/tag\/typescript\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">TypeScript<\/a>, och kommer att tilldela dem som nyckelv\u00e4rden i b\u00e5da riktningarna till motsvarande objekt.<\/p>\n<p>Och nu kan vi l\u00e4gga till ett par och fr\u00e5ga efter detta nya par<\/p>\n<pre><code>bimap.add(['d', 'D'])\nconsole.log( bimap.get('D')) <\/code><\/pre>\n<h2>En typs\u00e4ker dubbelriktad karta i TypeScript<\/h2>\n<p>F\u00f6r att g\u00f6ra saker b\u00e4ttre och skrivs\u00e4kra kan vi skriva om detta i TypeScript och l\u00e4gga till skrivkoncept som ett generiskt objekt vid initialisering av kartan och en <a href=\"https:\/\/www.typescriptlang.org\/docs\/handbook\/basic-types.html#tuple\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">tupel<\/a> n\u00e4r ett nytt element l\u00e4ggs till.<\/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>Denna skrivning g\u00f6r nu v\u00e5r karta helt s\u00e4ker och s\u00e4kerst\u00e4ller att vi i det h\u00e4r fallet alltid kommer att anv\u00e4nda str\u00e4ngar f\u00f6r b\u00e5de nycklar och v\u00e4rden.<\/p>\n<p><div id=\"PostUnique_PostSource\" style=\"padding-top: 50px\">Inspelningsk\u00e4lla:  <a target=\"_blank\" rel=\"noopener nofollow\" href=\"\/\/startfunction.com\" class=\"external external_icon\">startfunction.com<\/a><\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Du kan fr\u00e5ga dessa kartor efter nyckel och f\u00e5 dess v\u00e4rde eller efter v\u00e4rde och f\u00e5 dess nyckel<\/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":[848,734,901,755,724],"tags":[1173],"class_list":["post-231803","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-handledningar","category-javascript-9","category-koda","category-oeppen-kaella","category-utvecklaren","tag-affiai-sv"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/posts\/231803","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/comments?post=231803"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/posts\/231803\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/media\/224548"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/media?parent=231803"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/categories?post=231803"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/tags?post=231803"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}