<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: morcossameh</title>
    <description>The latest articles on Forem by morcossameh (@morcossameh).</description>
    <link>https://forem.com/morcossameh</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F987831%2Ffc63e0cb-04b8-456e-b3c5-40f9d765d465.jpeg</url>
      <title>Forem: morcossameh</title>
      <link>https://forem.com/morcossameh</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/morcossameh"/>
    <language>en</language>
    <item>
      <title>Implement simple Linked HashMap using PHP</title>
      <dc:creator>morcossameh</dc:creator>
      <pubDate>Tue, 20 Dec 2022 09:28:14 +0000</pubDate>
      <link>https://forem.com/morcossameh/implement-simple-linked-hashmap-using-php-54ak</link>
      <guid>https://forem.com/morcossameh/implement-simple-linked-hashmap-using-php-54ak</guid>
      <description>&lt;p&gt;Linked HashMap is a HashMap that stores the order of its items. Each item have a pointer to the previous inserted item and a pointer to the next Item.&lt;/p&gt;

&lt;p&gt;To handle the collision, we will use separate chaining technique for simplicity. For more information, you can refer to this &lt;a href="https://www.geeksforgeeks.org/separate-chaining-collision-handling-technique-in-hashing/"&gt;link&lt;/a&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  Linked HashMap Item
&lt;/h2&gt;

&lt;p&gt;First, let's create a class for the Linked HashMap item:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class LinkedHashMapItem {
    public $key;
    public $value;
    public $next;
    public $before;
    public $after;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;next: is used to handle the collision, if an item have the same hash code as another one, it will be stored in its this attribute.&lt;/li&gt;
&lt;li&gt;before: the item that is stored before the current item.&lt;/li&gt;
&lt;li&gt;after: the item that is store after the current item.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now, let's create the Linked HashMap class:&lt;/p&gt;

&lt;h2&gt;
  
  
  Linked HashMap Class
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class LinkedHashMap {
    protected $capacity;
    protected $array;
    protected $head;
    protected $tail;

    function __construct($capacity) {
        $this-&amp;gt;capacity = $capacity;
        $this-&amp;gt;array = array_fill(0, $capacity, null);
    }

    function getHead() {
        return is_null($this-&amp;gt;head) ? null : $this-&amp;gt;head-&amp;gt;value;
    }

    function getTail() {
        return is_null($this-&amp;gt;tail) ? null : $this-&amp;gt;tail-&amp;gt;value;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;capacity&lt;/code&gt; is used to store the length, the data is stored in &lt;code&gt;array&lt;/code&gt;, &lt;code&gt;head&lt;/code&gt; stores the first item and &lt;code&gt;tail&lt;/code&gt; stores the last one.&lt;/p&gt;

&lt;p&gt;let's make a simple hash function that calculates the hash code based on the modulo result of the key and the capacity. Here it is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;private function calculateHash($value) {
    if(is_string($value)) {
        return ord($value[0]) % $this-&amp;gt;capacity;
    } elseif(is_numeric($value)) {
        return $value % $this-&amp;gt;capacity;
    }
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We need to make the &lt;code&gt;put&lt;/code&gt; function that is responsible for adding new elements to our Linked HashMap.&lt;/p&gt;

&lt;h2&gt;
  
  
  The put function
&lt;/h2&gt;

&lt;p&gt;In order to insert a new item, we need first to calculate the hash code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$hash = $this-&amp;gt;calculateHash($key);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we need to build the new item object, change assignment of the tail and the head if needed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$newItem = new LinkedHashMapItem();
$newItem-&amp;gt;key = $key;
$newItem-&amp;gt;value = $value;

$lastAddedItem = $this-&amp;gt;tail;
$newItem-&amp;gt;before = $lastAddedItem;

if(!is_null($this-&amp;gt;head)) {
    $lastAddedItem-&amp;gt;after = $newItem;
}

if(is_null($this-&amp;gt;head)) {
    $this-&amp;gt;head = $newItem;
}
$this-&amp;gt;tail = $newItem;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, let's check if a collision exists or not. If there is a collision, we will handle it by getting the last element inserted in this particular position and append the new element to it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$lastItem = $this-&amp;gt;array[$hash];
while(!is_null($lastItem-&amp;gt;next)) {
    $lastItem = $lastItem-&amp;gt;next;
}
$lastItem-&amp;gt;next = $newItem;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If no collision exists, we will just add the new element:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$this-&amp;gt;array[$hash] = $newItem;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's all for the &lt;code&gt;put&lt;/code&gt; function, let's move to the &lt;code&gt;get&lt;/code&gt; function.&lt;/p&gt;

&lt;h2&gt;
  
  
  The get function
&lt;/h2&gt;

&lt;p&gt;This one is simple and straightforward. First, we need to calculate the hash code. Next, we will loop the position until we match the keys. If the key is not found, just return -1.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function get($key) {
    $hash = $this-&amp;gt;calculateHash($key);

    $item = $this-&amp;gt;array[$hash];
    do {
        if($item-&amp;gt;key === $key) {
            return $item-&amp;gt;value;
        }
        $item = $item-&amp;gt;next;
    } while(!is_null($item));

    return -1;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Final Result
&lt;/h2&gt;

&lt;p&gt;After combining the previous snippets, the final LinkedHashMap class should be something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class LinkedHashMap {
    protected $capacity;
    protected $array;
    protected $head;
    protected $tail;

    function __construct($capacity) {
        $this-&amp;gt;capacity = $capacity;
        $this-&amp;gt;array = array_fill(0, $capacity, null);
    }

    function getHead() {
        return is_null($this-&amp;gt;head) ? null : $this-&amp;gt;head-&amp;gt;value;
    }

    function getTail() {
        return is_null($this-&amp;gt;tail) ? null : $this-&amp;gt;tail-&amp;gt;value;
    }

    function get($key) {
        $hash = $this-&amp;gt;calculateHash($key);

        $item = $this-&amp;gt;array[$hash];
        do {
            if($item-&amp;gt;key === $key) {
                return $item-&amp;gt;value;
            }
            $item = $item-&amp;gt;next;
        } while(!is_null($item));

        return -1;
    }

    function put($key, $value) {
        $hash = $this-&amp;gt;calculateHash($key);
        $newItem = $this-&amp;gt;buildNewItem($key, $value);
        if(is_null($this-&amp;gt;array[$hash])) {
            $this-&amp;gt;array[$hash] = $newItem;
        } else {
            $lastItemInHash = $this-&amp;gt;getLastItemInHash($hash);
            $lastItemInHash-&amp;gt;next = $newItem;
        }
    }

    private function buildNewItem($key, $value) {
        $newItem = new LinkedHashMapItem();
        $newItem-&amp;gt;key = $key;
        $newItem-&amp;gt;value = $value;

        $lastAddedItem = $this-&amp;gt;tail;
        $newItem-&amp;gt;before = $lastAddedItem;

        if(!is_null($this-&amp;gt;head)) {
            $lastAddedItem-&amp;gt;after = $newItem;
        }

        if(is_null($this-&amp;gt;head)) {
            $this-&amp;gt;head = $newItem;
        }
        $this-&amp;gt;tail = $newItem;

        return $newItem;
    }

    private function getLastItemInHash($hash) {
        $lastItem = $this-&amp;gt;array[$hash];
        while(!is_null($lastItem-&amp;gt;next)) {
            $lastItem = $lastItem-&amp;gt;next;
        }
        return $lastItem;
    }

    private function calculateHash($value) {
        if(is_string($value)) {
            return ord($value[0]) % $this-&amp;gt;capacity;
        } elseif(is_numeric($value)) {
            return $value % $this-&amp;gt;capacity;
        }
        return 0;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>php</category>
      <category>datastructure</category>
      <category>laravel</category>
    </item>
  </channel>
</rss>
