<?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: ohaddahan</title>
    <description>The latest articles on Forem by ohaddahan (@ohaddahan).</description>
    <link>https://forem.com/ohaddahan</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%2F233801%2Facd10bc0-9d7e-4dff-b671-ca5c4144d9be.png</url>
      <title>Forem: ohaddahan</title>
      <link>https://forem.com/ohaddahan</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/ohaddahan"/>
    <language>en</language>
    <item>
      <title>Tips for safer dependency management in JavaScript environments</title>
      <dc:creator>ohaddahan</dc:creator>
      <pubDate>Sun, 21 Jan 2024 16:56:57 +0000</pubDate>
      <link>https://forem.com/ohaddahan/tips-for-safer-dependency-management-in-javascript-environments-1f6c</link>
      <guid>https://forem.com/ohaddahan/tips-for-safer-dependency-management-in-javascript-environments-1f6c</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flg64youncuy41gksf37m.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flg64youncuy41gksf37m.jpeg" alt="Image description" width="740" height="532"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Just about anyone who worked on the JavaScript ecosystem has faced annoying issues due to version mismatch , dependencies updates etc. , I want to share a few small tips that helped me mitigate some of the issues.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tip #1 &lt;a href="https://docs.npmjs.com/cli/v9/using-npm/config#save-exact"&gt;save-exact&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;npm install &amp;lt;package-name&amp;gt; --save-exact&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This will install the package exact version instead of default range.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;"dependencies": {&lt;br&gt;
    "axios": "1.6.5"&lt;br&gt;
}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Due note that &lt;code&gt;package-lock.json&lt;/code&gt; will still contain ranges. One way to mitigate this is to manually edit the file, a simple &lt;code&gt;regex&lt;/code&gt; will enforce exact versions on the dependencies too.&lt;/p&gt;

&lt;p&gt;(if some dependencies requirements can't be fulfilled with strict nested versions, you can iterate until you find a set of matching versions and make them static)&lt;/p&gt;

&lt;p&gt;For example running the code below in &lt;code&gt;vim&lt;/code&gt; editor.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;%s/: "\^/: "/g&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You can set it as the default behavior by running.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm config set save-exact=true&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Which will set &lt;code&gt;save-exact=true&lt;/code&gt; in your &lt;code&gt;.npmrc&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tip #2 avoid named releases
&lt;/h2&gt;

&lt;p&gt;One way to help synchronize multiple developers working on the same repository is using &lt;code&gt;nvm&lt;/code&gt; (or similar) with the appropriate &lt;code&gt;rc&lt;/code&gt; file such as &lt;code&gt;.nvmrc&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;nvm&lt;/code&gt; supports named versions which might look nicer on a first look but generates various issues, since these versions aren't static.&lt;/p&gt;

&lt;p&gt;Causing issues with compatibility with various dependencies , and other random issues such as running &lt;code&gt;nvm use&lt;/code&gt; but it no longer finds the version, since it was updated and you need to reinstall it locally.&lt;/p&gt;

&lt;p&gt;It's even more problematic once you take into account &lt;code&gt;CI/CD&lt;/code&gt; since they reinstall the environment from scratch each time and it will probably differ from local developers environment that haven't yet update to the latests named version update.&lt;/p&gt;

&lt;p&gt;Hence I highly recommend using a version number and simply change it as needed, knowingly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tip #3 use &lt;a href="https://docs.npmjs.com/cli/v10/configuring-npm/package-json#engines"&gt;engines&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Basically an expansion on #2 , explicitly name the &lt;code&gt;node&lt;/code&gt; / &lt;code&gt;npm&lt;/code&gt; version (strict, not a range!) to avoid more unexpected and unwanted surprises.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tip #4 use &lt;a href="https://docs.npmjs.com/cli/v9/using-npm/config#engine-strict"&gt;engine-strict&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Avoid installing potential packages that might cause issues.&lt;/p&gt;

&lt;p&gt;It's better to resolve an issue early on, with little overhead at the start than fixing it later when it's a critical part of your system.&lt;/p&gt;

</description>
      <category>node</category>
      <category>packagejson</category>
      <category>dependecymanagment</category>
      <category>npm</category>
    </item>
    <item>
      <title>Reducing egress costs for dummies (R2 vs S3)</title>
      <dc:creator>ohaddahan</dc:creator>
      <pubDate>Sun, 21 Jan 2024 16:41:33 +0000</pubDate>
      <link>https://forem.com/ohaddahan/reducing-egress-costs-for-dummies-r2-vs-s3-5ok</link>
      <guid>https://forem.com/ohaddahan/reducing-egress-costs-for-dummies-r2-vs-s3-5ok</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F20p4rc0wcwq8j1it6x8n.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F20p4rc0wcwq8j1it6x8n.jpeg" alt="Image description" width="740" height="508"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One day I was checking &lt;a href="http://cloudflare.com/"&gt;CloudFlare&lt;/a&gt; dashboard I noticed that one of the endpoints we were using to deliver new versions has huge bandwidth spikes.&lt;/p&gt;

&lt;p&gt;Each new version we released was automatically downloaded by thousands of clients, resulting in terra bytes of egress costs to &lt;a href="https://aws.amazon.com/s3/"&gt;S3&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;At the current rate this was around &lt;a href="https://calculator.aws/#/createCalculator/S3"&gt;3,000$/month&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Furthermore, our plan was to move to a daily release, which will make this problem even worse and jump to &lt;a href="https://calculator.aws/#/createCalculator/S3"&gt;~50,000$/month&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I immediately tried to think how to resolve this issue.&lt;/p&gt;

&lt;p&gt;Since all the content we deliver on a new update is identical copies of the same new version, caching jumped into mind.&lt;/p&gt;

&lt;p&gt;But unfortunately &lt;a href="https://aws.amazon.com/cloudfront/"&gt;CloudFront&lt;/a&gt; costs weren't much better at around &lt;a href="https://calculator.aws/#/createCalculator/CloudFront"&gt;2,500$/month&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Being a big fan of &lt;a href="http://cloudflare.com/"&gt;CloudFlare&lt;/a&gt; I knew of &lt;a href="https://www.cloudflare.com/developer-platform/r2/"&gt;R2&lt;/a&gt; and quickly &lt;a href="https://www.cloudflare.com/pg-cloudflare-r2-vs-aws-s3/#htmlIdPlansMatrix"&gt;calculated&lt;/a&gt; that using &lt;a href="https://www.cloudflare.com/developer-platform/r2/"&gt;R2&lt;/a&gt; will reduce the costs to effectively  zero.&lt;/p&gt;

&lt;p&gt;Implementing this was quite easy, simply store and serve from &lt;a href="https://www.cloudflare.com/developer-platform/r2/"&gt;R2&lt;/a&gt; instead of &lt;a href="https://aws.amazon.com/s3/"&gt;S3&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Another bonus was faster download speed.&lt;/p&gt;

</description>
      <category>cloudflare</category>
      <category>aws</category>
      <category>r2</category>
      <category>s3</category>
    </item>
    <item>
      <title>How to secure SSH server</title>
      <dc:creator>ohaddahan</dc:creator>
      <pubDate>Sun, 21 Jan 2024 16:35:19 +0000</pubDate>
      <link>https://forem.com/ohaddahan/how-to-secure-ssh-server-12a6</link>
      <guid>https://forem.com/ohaddahan/how-to-secure-ssh-server-12a6</guid>
      <description>&lt;h2&gt;
  
  
  Disable root login
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Create new user &lt;code&gt;useradd -m  username&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Set password &lt;code&gt;passwd username&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;Optional&lt;/em&gt;&lt;/strong&gt;: Add user to sudoers &lt;code&gt;usermod -aG sudo username&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Edit &lt;code&gt;/etc/ssh/ssh_config&lt;/code&gt; or &lt;code&gt;/etc/ssh/sshd_config&lt;/code&gt; and add:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Authentication:&lt;/span&gt;
PermitRootLogin no
AllowUsers username
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Might need to look for other config files being included that might override this setting (&lt;code&gt;grep -r "PermitRootLogin" /etc/ssh/&lt;/code&gt;).&lt;/p&gt;

&lt;h2&gt;
  
  
  Harden SSH
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Disable empty password:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;PermitEmptyPasswords no
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Limit the number of authentication tries per connection:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;MaxAuthTries 3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Changed to &lt;code&gt;ssh&lt;/code&gt; version 2:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Include /etc/ssh/sshd_config.d/&lt;span class="k"&gt;*&lt;/span&gt;.conf
Protocol 2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Disable plain text authentication
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Connecting with SSH key:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;UsePAM no
PasswordAuthentication no
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh-keygen 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Restart SSH service
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Restart &lt;code&gt;ssh&lt;/code&gt; service &lt;code&gt;sudo systemctl restart ssh&lt;/code&gt; or &lt;code&gt;sudo systemctl restart sshd&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Prevent brute force attacks
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Install &lt;a href="https://github.com/fail2ban/fail2ban"&gt;fail2ban&lt;/a&gt; or &lt;a href="https://www.sshguard.net/"&gt;sshguard&lt;/a&gt; to ban IPs that fail to authenticate after a certain number of attempts.&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  References
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.makeuseof.com/improve-your-linux-server-security-with-these-hardening-steps/"&gt;13 Ways to secure SSH server&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.cyberciti.biz/faq/how-to-set-up-ssh-keys-on-linux-unix/"&gt;How To Set up SSH Keys on a Linux / Unix System&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://linux.die.net/man/5/sshd_config"&gt;sshd_config&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://linux.die.net/man/5/ssh_config"&gt;ssh_config&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://linux.die.net/man/1/ssh-keygen"&gt;ssh-keygen&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://linux.die.net/man/8/useradd"&gt;useradd&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://linux.die.net/man/1/passwd"&gt;passwd&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://linux.die.net/man/8/usermod"&gt;usermod&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/fail2ban/fail2ban"&gt;fail2ban&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.sshguard.net/"&gt;sshguard&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ssh</category>
      <category>security</category>
      <category>root</category>
      <category>sudo</category>
    </item>
    <item>
      <title>Using data/computer science to solve a real life auto-complete issue</title>
      <dc:creator>ohaddahan</dc:creator>
      <pubDate>Fri, 29 Nov 2019 23:58:43 +0000</pubDate>
      <link>https://forem.com/ohaddahan/using-data-science-to-solve-a-real-life-auto-complete-issue-37d2</link>
      <guid>https://forem.com/ohaddahan/using-data-science-to-solve-a-real-life-auto-complete-issue-37d2</guid>
      <description>&lt;h1&gt;
  
  
  Using data science to solve a real life auto complete issue
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Problem background
&lt;/h2&gt;

&lt;p&gt;In one of the applications I maintain, we had to create an auto complete with 20,000 options.&lt;/p&gt;

&lt;p&gt;There is no typo, 20,000 is the real number.&lt;/p&gt;

&lt;p&gt;So I looked up how to do an auto complete and I implemented it with a &lt;code&gt;datalist&lt;/code&gt;, something that looked roughly&lt;br&gt;
like this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;list=&lt;/span&gt;&lt;span class="s"&gt;"datalist"&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"datalist"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;datalist&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"datalist"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;option&amp;gt;&lt;/span&gt;1&lt;span class="nt"&gt;&amp;lt;/option&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;option&amp;gt;&lt;/span&gt;2&lt;span class="nt"&gt;&amp;lt;/option&amp;gt;&lt;/span&gt;
  ...
  ...
  &lt;span class="nt"&gt;&amp;lt;option&amp;gt;&lt;/span&gt;19,999&lt;span class="nt"&gt;&amp;lt;/option&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;option&amp;gt;&lt;/span&gt;20,000&lt;span class="nt"&gt;&amp;lt;/option&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/datalist&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The problem was, that this is VERY SLOW, each time a user inserted a character, it will trigger an iteration on &lt;br&gt;
the entire 20,000 options and check for each one of them which is slow, especially since I actually only need to&lt;br&gt;
compare the prefix and &lt;code&gt;datalist&lt;/code&gt; compares if the input string is contained in the options and not if they start with it.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;option&amp;gt;&lt;/span&gt;dog food&lt;span class="nt"&gt;&amp;lt;/option&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;option&amp;gt;&lt;/span&gt;cat food&lt;span class="nt"&gt;&amp;lt;/option&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;option&amp;gt;&lt;/span&gt;dogs and cats&lt;span class="nt"&gt;&amp;lt;/option&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;option&amp;gt;&lt;/span&gt;cats and dogs&lt;span class="nt"&gt;&amp;lt;/option&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this case, inserting &lt;code&gt;dog&lt;/code&gt; will match all but &lt;code&gt;cat food&lt;/code&gt; while the user is interested only in options starting with &lt;code&gt;dog&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This is an &lt;code&gt;O(n)&lt;/code&gt; time complexity and it wasn't good enough.&lt;/p&gt;

&lt;h2&gt;
  
  
  Trie Tree
&lt;/h2&gt;

&lt;p&gt;Trying to find a solution, I was thinking to myself, auto complete need doesn't care about any string that isn't&lt;br&gt;
starting with the current input. Hence if I'll restructure my data in the form of a tree I'll be able to start &lt;br&gt;
my check from the relevant place and not iterate over all options each time.&lt;/p&gt;

&lt;p&gt;As it turns out, I didn't need to reinvent the wheel, people already thought about it, created it long before me.&lt;br&gt;
This type of structure is called a &lt;a href="https://en.wikipedia.org/wiki/Trie"&gt;trie tree&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;A nice visualisation cant be found at &lt;a href="https://www.cs.usfca.edu/~galles/visualization/Trie.html"&gt;trie tree visualization&lt;/a&gt;.&lt;br&gt;
(Keep in mind that the find method implemented in the visualization only check for exact match which isn't our case)&lt;/p&gt;

&lt;p&gt;Fortunately there are plenty of &lt;a href="https://gist.github.com/tpae/72e1c54471e88b689f85ad2b3940a8f0"&gt;simple trie tree implementation&lt;/a&gt;.&lt;br&gt;
And I saved myself lots of time writing it from scratch.&lt;/p&gt;
&lt;h2&gt;
  
  
  End Result
&lt;/h2&gt;

&lt;p&gt;The end result can be seen in &lt;a href="https://jsfiddle.net/ohaddahan/q9mx7yoe/"&gt;sandbox example&lt;/a&gt;.&lt;br&gt;
Inserting any string into the original &lt;code&gt;datalist&lt;/code&gt; input will take significantly more time&lt;br&gt;
and will show too many unrelated results. Using the &lt;code&gt;trie&lt;/code&gt; based auto complete is considerably faster and doesn't show &lt;br&gt;
unneeded data, two wins with one change! :)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;label&amp;gt;&lt;/span&gt;Data List&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;list=&lt;/span&gt;&lt;span class="s"&gt;"dropdown_menu"&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"example"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;datalist&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"dropdown_menu"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/datalist&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;br&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;label&amp;gt;&lt;/span&gt;Trie Tree&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"trie_tree"&lt;/span&gt; &lt;span class="na"&gt;onkeyup=&lt;/span&gt;&lt;span class="s"&gt;"updateTrie()"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;ul&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"trie_menu"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Here comes code from https://gist.github.com/tpae/72e1c54471e88b689f85ad2b3940a8f0&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;trie&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Trie&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;makeid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;           &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;characters&lt;/span&gt;       &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;charactersLength&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;characters&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;characters&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;charAt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;floor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;charactersLength&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
   &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;datalist&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dropdown_menu&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;10000&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;makeid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;option&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;option&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;option&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;option&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;value&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createTextNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;option&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;datalist&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;option&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;trie&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;removeAllChildNodes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;firstChild&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;removeChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;firstChild&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;updateTrie&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;trie_el&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;trie_tree&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;trie_menu&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;trie_menu&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;removeAllChildNodes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;trie_menu&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;trie_el&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;trie&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;tmp_text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
      &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;li&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;li&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;li&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;tmp_text&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;      
      &lt;span class="nx"&gt;trie_menu&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;li&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>javascript</category>
      <category>html</category>
    </item>
    <item>
      <title>React based Chrome extension with one click</title>
      <dc:creator>ohaddahan</dc:creator>
      <pubDate>Mon, 14 Oct 2019 19:42:01 +0000</pubDate>
      <link>https://forem.com/ohaddahan/react-based-chrome-extension-with-one-click-3m77</link>
      <guid>https://forem.com/ohaddahan/react-based-chrome-extension-with-one-click-3m77</guid>
      <description>&lt;h4&gt;
  
  
  The Goals
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Build a Chrome extension&lt;/li&gt;
&lt;li&gt;Base the extension on React&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Instructions
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;git clone https://github.com/ohaddahan/how-to-build-react-chrome-extension&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;cd how-to-build-react-chrome-extension&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;./scripts/run.sh&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Load the unpacked extension into Chrome&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  The details
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;./scripts/run.sh&lt;/code&gt; is a fairly simple shell script to follow , here is how it works:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Setup and use &lt;code&gt;nvm&lt;/code&gt; , this part optional , and you comment this section if you like.
I left it since I think it's easier to avoid version mismatches with &lt;code&gt;nvm&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Create the React application by running &lt;code&gt;npx create-react-app ${extName} --use-npm&lt;/code&gt; where &lt;code&gt;extName&lt;/code&gt; is an environment variable with default value &lt;code&gt;react-chrome-extension&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Install dependencies &lt;code&gt;npm install npm-run-all webpack-cli axios @material-ui/core chalk&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Copy &lt;code&gt;contentScript.js&lt;/code&gt; and &lt;code&gt;background.js&lt;/code&gt; sample files from my repo into the new extension &lt;code&gt;src&lt;/code&gt; directory.&lt;/li&gt;
&lt;li&gt;Copy over the &lt;code&gt;scripts&lt;/code&gt; and &lt;code&gt;icons&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;node scripts/prep.js&lt;/code&gt; (will elaborate on it later).&lt;/li&gt;
&lt;li&gt;Finally it will build our extension using &lt;code&gt;npm run build&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why all these extra scripts?
&lt;/h2&gt;

&lt;p&gt;Let me elaborate on the various issues I encountered while getting this to work.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;package.json&lt;/code&gt; compatibility issues:

&lt;ul&gt;
&lt;li&gt;Changes done to &lt;code&gt;pacakge.json&lt;/code&gt; by &lt;code&gt;./scripts/prep.js&lt;/code&gt;:
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;  &lt;span class="nx"&gt;packageJSON&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;scripts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;start&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-scripts start&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;eject&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-scripts eject&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;test&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-scripts test&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;prebuild&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rm -fr build ; node scripts/validate.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;build&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;npm-run-all build:*&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;build:app&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;INLINE_RUNTIME_CHUNK=false react-scripts build&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;build:files&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;node ./scripts/build.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;prezip&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rm -fr *.zip&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;zip&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;npm-run-all zip:*&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;zip:build&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;cd build; zip -r ../build.zip * -x '*.DS_Store'&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;zip:src&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;zip -r src.zip src package.json README.md public -x '*.DS_Store'&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;release&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;npm-run-all build zip&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
   &lt;span class="p"&gt;};&lt;/span&gt;
   &lt;span class="nx"&gt;packageJSON&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;eslintConfig&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;extends&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-app&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There were no changes done to &lt;code&gt;start&lt;/code&gt; , &lt;code&gt;eject&lt;/code&gt; and &lt;code&gt;test&lt;/code&gt;.&lt;br&gt;&lt;br&gt;
  &lt;code&gt;prezip&lt;/code&gt; , &lt;code&gt;zip&lt;/code&gt; , &lt;code&gt;zip:build&lt;/code&gt; , &lt;code&gt;zip:src&lt;/code&gt; and &lt;code&gt;release&lt;/code&gt; are just regular helpers needed for any Chrome extension.                                                                                                 &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;prebuild&lt;/code&gt; first cleans up the previous build and then runs &lt;code&gt;./scripts/validate.js&lt;/code&gt; &lt;br&gt;
all this script does is check that &lt;code&gt;package.json&lt;/code&gt; and &lt;code&gt;manifiest.json&lt;/code&gt; are valid &lt;code&gt;JSON&lt;/code&gt; files and that the required&lt;br&gt;
Chrome settings exist.&lt;br&gt;
(some of the settings I used aren't really mandatory but are a very common case and you can remove them if you have such a special case&lt;br&gt;
&lt;code&gt;icons&lt;/code&gt; and &lt;code&gt;browser_action&lt;/code&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The use of &lt;code&gt;npm-run-all&lt;/code&gt; is purely for ease of use to run multiple targets from one target.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Since we're using &lt;code&gt;create-react-app&lt;/code&gt; it will use &lt;code&gt;react-scripts build&lt;/code&gt; which doesn't expect to be used&lt;br&gt;
as an extension. The first thing we need to change is adding &lt;code&gt;INLINE_RUNTIME_CHUNK=false&lt;/code&gt; before &lt;code&gt;react-scripts build&lt;/code&gt;.&lt;br&gt;
This is done inside &lt;code&gt;package.json&lt;/code&gt; , under &lt;code&gt;scripts&lt;/code&gt; key , you can see the result in the final file create by &lt;code&gt;scripts/run.sh&lt;/code&gt;.&lt;br&gt;
If we won't use this flag Chrome will not run React properly and raise a&lt;br&gt;
Content Security Policy error since React will try to inline JavaScript code.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;package.json&lt;/code&gt; at  &lt;code&gt;scripts&lt;/code&gt; key , &lt;code&gt;"build:app": "INLINE_RUNTIME_CHUNK=false react-scripts build"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://create-react-app.dev/docs/advanced-configuration"&gt;Create React App - Advanced Configuration&lt;/a&gt;
&amp;gt; By default, Create React App will embed the runtime script into index.html during the production build.
When set to false, the script will not be embedded and will be imported as usual.
This is normally required when dealing with CSP.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://developer.chrome.com/extensions/contentSecurityPolicy"&gt;Content Security Policy (CSP)&lt;/a&gt;
&amp;gt; Inline JavaScript will not be executed.
This restriction bans both inline &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; blocks and inline event handlers (e.g. &lt;code&gt;&amp;lt;button onclick="..."&amp;gt;&lt;/code&gt;).
The first restriction wipes out a huge class of cross-site scripting attacks by making it impossible for you to
accidentally execute script provided by a malicious third-party.
It does, however, require you to write your code with a clean separation between content and behavior 
(which you should of course do anyway, right?). An example might make this clearer.
You might try to write a Browser Action's popup as a single popup.html containing&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;

&lt;p&gt;&lt;code&gt;script/build.js&lt;/code&gt; is the last helper script we have, it simply runs &lt;code&gt;npx webpack&lt;/code&gt; on the &lt;code&gt;contentScript.js&lt;/code&gt; &lt;br&gt;
and &lt;code&gt;background.js&lt;/code&gt; , after that it copies them into the build directory since &lt;code&gt;react-scripts&lt;/code&gt; won't do it for us.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;manifest.json&lt;/code&gt; compatibility issues:&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We add &lt;code&gt;version&lt;/code&gt; and &lt;code&gt;manifest_version&lt;/code&gt; which &lt;code&gt;create-react-app&lt;/code&gt; doesn't add but Chrome demands.&lt;br&gt;&lt;br&gt;
We also add &lt;code&gt;icons&lt;/code&gt; which isn't mandatory but comes as an incompatible format from &lt;code&gt;create-react-app&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We remove &lt;code&gt;background_color&lt;/code&gt;, &lt;code&gt;display&lt;/code&gt;, &lt;code&gt;start_url&lt;/code&gt; and  &lt;code&gt;theme_color&lt;/code&gt; which come from &lt;code&gt;create-react-app&lt;/code&gt; but &lt;br&gt;&lt;br&gt;
aren't compatible with Chrome.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We also add &lt;code&gt;browser_action&lt;/code&gt; , &lt;code&gt;content_scripts&lt;/code&gt; , &lt;code&gt;permissions&lt;/code&gt; , &lt;code&gt;content_security_policy&lt;/code&gt; , &lt;code&gt;background&lt;/code&gt;&lt;br&gt;&lt;br&gt;
which aren't mandatory but most likely needed by most and is missing.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Background and Content Scripts
&lt;/h4&gt;

&lt;p&gt;Included are simple &lt;code&gt;background.js&lt;/code&gt; and &lt;code&gt;contentScript.js&lt;/code&gt; which send a &lt;code&gt;GET&lt;/code&gt; request to &lt;code&gt;https://postman-echo.com/get&lt;/code&gt;.&lt;br&gt;
The reason I included them is mainly for completeness and as a reference for others on how they work with a React-Chrome-Extension.&lt;br&gt;
Furthermore they are also an example of &lt;code&gt;chrome.runtime&lt;/code&gt; &lt;/p&gt;

&lt;h4&gt;
  
  
  What does it actually do?
&lt;/h4&gt;

&lt;p&gt;This sample extension will add a &lt;code&gt;div&lt;/code&gt; and a &lt;code&gt;button&lt;/code&gt; inside it , as seen in the image below.&lt;br&gt;
Once you click on the button it will send  a &lt;code&gt;GET&lt;/code&gt; request to &lt;code&gt;https://postman-echo.com/get&lt;/code&gt; and print the response.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Vl4-Z_ti--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/ohaddahan/how-to-build-react-chrome-extension/master/images/image2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Vl4-Z_ti--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/ohaddahan/how-to-build-react-chrome-extension/master/images/image2.png" alt="How it looks"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  How to load and debug it?
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gMXFmYke--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/ohaddahan/how-to-build-react-chrome-extension/master/images/image1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gMXFmYke--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/ohaddahan/how-to-build-react-chrome-extension/master/images/image1.png" alt="Load and background script"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--OzGtLjZ0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/ohaddahan/how-to-build-react-chrome-extension/master/images/image4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OzGtLjZ0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/ohaddahan/how-to-build-react-chrome-extension/master/images/image4.png" alt="Chrome console"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--eOj27AeB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/ohaddahan/how-to-build-react-chrome-extension/master/images/image5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--eOj27AeB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/ohaddahan/how-to-build-react-chrome-extension/master/images/image5.png" alt="Background console"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Load the unpacked extension , make sure you're in developer mode and you select the &lt;code&gt;build&lt;/code&gt; directory.&lt;br&gt;
For more details see :&lt;br&gt;
&lt;a href="https://levelup.gitconnected.com/how-to-use-react-js-to-create-chrome-extension-in-5-minutes-2ddb11899815"&gt;How to use React.js to create a cross-browser extension in 5 minutes&lt;/a&gt;&lt;br&gt;
&lt;a href="https://developer.chrome.com/extensions/getstarted"&gt;Chrome - Getting Started Tutorial&lt;/a&gt; and &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Enable background scripts , click on &lt;code&gt;background page (Inactive)&lt;/code&gt; and it will turn to &lt;code&gt;background page&lt;/code&gt;.&lt;br&gt;
And open &lt;code&gt;DevTools&lt;/code&gt; for the background scripts, without this you won't see any &lt;code&gt;console.log&lt;/code&gt; or &lt;br&gt;
any other action done in the background&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Inside your regular Chrome , open &lt;code&gt;DevTools&lt;/code&gt; and you'll see the prints coming from &lt;code&gt;contentScript.js&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The response from &lt;code&gt;https://postman-echo.com/get&lt;/code&gt; inside &lt;code&gt;DevTools&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The background &lt;code&gt;DevTools&lt;/code&gt; as you can see by the title.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The prints from &lt;code&gt;background.js&lt;/code&gt; and response from &lt;code&gt;https://postman-echo.com/get&lt;/code&gt; inside &lt;code&gt;DevTools&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Final thoughts
&lt;/h4&gt;

&lt;p&gt;While trying to do this I was trying to follow a few other examples as shown in the references section.&lt;br&gt;
Unfortunately none had all the elements I needed or explained all the details I elaborate on here.&lt;br&gt;
I hope this will help anyone else who would like to create a React-Chrome-Extension.&lt;br&gt;
(I'm sure my code can get better, open an issue on &lt;code&gt;GitHub&lt;/code&gt; and I'll happily fix it)  &lt;/p&gt;

&lt;h4&gt;
  
  
  References
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://levelup.gitconnected.com/how-to-use-react-js-to-create-chrome-extension-in-5-minutes-2ddb11899815"&gt;How to use React.js to create a cross-browser extension in 5 minutes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/jhen0409/react-chrome-extension-boilerplate"&gt;React Chrome Extension Boilerplate&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://itnext.io/create-chrome-extension-with-reactjs-using-inject-page-strategy-137650de1f39#3996"&gt;Create chrome extension with ReactJs using inject page strategy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/FullStack-Academy-Kiev/react-chrome-extension"&gt;Chrome Extension boilerplate with ReactJS and vanilla JS examples&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.chrome.com/extensions/contentSecurityPolicy"&gt;Content Security Policy (CSP)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://create-react-app.dev/docs/advanced-configuration"&gt;Create React App - Advanced Configuration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.chrome.com/extensions/runtime"&gt;chrome.runtime - Official Docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.chrome.com/extensions/getstarted"&gt;Chrome - Getting Started Tutorial&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>chrome</category>
      <category>extension</category>
    </item>
    <item>
      <title>Algorithm Optimisation: A Real Example - My insights</title>
      <dc:creator>ohaddahan</dc:creator>
      <pubDate>Wed, 02 Oct 2019 20:21:52 +0000</pubDate>
      <link>https://forem.com/ohaddahan/algorithm-optimisation-a-real-example-my-insights-4211</link>
      <guid>https://forem.com/ohaddahan/algorithm-optimisation-a-real-example-my-insights-4211</guid>
      <description>&lt;p&gt;&lt;a class="mentioned-user" href="https://dev.to/steadbytes"&gt;@steadbytes&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;This week I read &lt;a href="https://dev.to/steadbytes/algorithm-optimisation-a-real-example-4988"&gt;Algorithm Optimisation: A Real Example&lt;/a&gt; and I recommend you all to read it too.&lt;br&gt;
It's a good article.&lt;/p&gt;

&lt;p&gt;I do think some items can be improved and I'll elaborate on them here.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;When dealing with a large range , plots should be logarithmic to improve visibility. In &lt;a href="https://dev.to/steadbytes/algorithm-optimisation-a-real-example-4988"&gt;Algorithm Optimisation: A Real Example&lt;/a&gt; the plots are in raw values , making the different curves and points on the curves unusable.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When benchmarking , we should remove outliers , the samples set being used by &lt;a href="https://dev.to/steadbytes/algorithm-optimisation-a-real-example-4988"&gt;Algorithm Optimisation: A Real Example&lt;/a&gt; &lt;code&gt;[1000 , 10000 , 100000 , 500000 , 1000000 , 2000000 , 5000000 , 10000000 , 20000000 , 50000000 , 100000000 , 200000000 , 500000000]&lt;/code&gt;&lt;br&gt;
Sample points &lt;code&gt;1000 , 10000&lt;/code&gt; are too small and are too susceptible to noise (the buffer size used is 4096). From my tests these sample points vary too much and their results doesn't reflect the 10X size difference.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When benchmarking , we should run the same test multiple times , one iteration isn't enough. For example , the machine used to run might be under a different load and if we only run once we won't be able to mitigate this effect. Hence I used &lt;a href="https://github.com/evanphx/benchmark-ips"&gt;Benchmark IPS&lt;/a&gt; to run each test multiple times.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Furthermore , while the actual solution given by &lt;a href="https://dev.to/steadbytes/algorithm-optimisation-a-real-example-4988"&gt;Algorithm Optimisation: A Real Example&lt;/a&gt; is very good and show out of box thinking.&lt;br&gt;
I suggest a different , much simpler solution that also have better performance.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/steadbytes/algorithm-optimisation-a-real-example-4988"&gt;Algorithm Optimisation: A Real Example&lt;/a&gt; still requires a &lt;code&gt;malloc&lt;/code&gt; call the size of the file being read.&lt;br&gt;
My proposed solution is instead of using the innovative linked list , we simply allocate all the memory needed beforehand and read the file directly into out result variable.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;while ((read_len = read(fd, *data + len, BUFSIZE)) &amp;gt; 0) {
      len += read_len;
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This gives us almost 2X on our largest sample point of &lt;code&gt;100000000&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PuNFa1tI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/vheui9vbn33s09zxsatt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PuNFa1tI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/vheui9vbn33s09zxsatt.png" alt="Original vs. Improved vs. Improved2"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Z0pYwkbg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/dlpy4smagnqml8gwh3jq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Z0pYwkbg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/dlpy4smagnqml8gwh3jq.png" alt="Improved / Improved2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://gist.github.com/ohaddahan/ac1140f4a7b8b159defb0cd9b6af8f46"&gt;Code gist&lt;/a&gt;&lt;/p&gt;

</description>
      <category>cpp</category>
      <category>ruby</category>
    </item>
    <item>
      <title>Nested data structure extractors</title>
      <dc:creator>ohaddahan</dc:creator>
      <pubDate>Sat, 21 Sep 2019 12:42:56 +0000</pubDate>
      <link>https://forem.com/ohaddahan/nested-data-structure-extractors-4p0i</link>
      <guid>https://forem.com/ohaddahan/nested-data-structure-extractors-4p0i</guid>
      <description>&lt;p&gt;Wanted to share a few helpful methods I use to traverse and extract data from nested data structures, usually 3rd party API responses.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;input_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="ss"&gt;x: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="ss"&gt;z: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="ss"&gt;first_name: &lt;/span&gt;&lt;span class="s1"&gt;'hello'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="ss"&gt;last_name: &lt;/span&gt;&lt;span class="s1"&gt;'world'&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="ss"&gt;q: &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="ss"&gt;z: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="ss"&gt;first_name: &lt;/span&gt;&lt;span class="s1"&gt;'hello'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="ss"&gt;last_name: &lt;/span&gt;&lt;span class="s1"&gt;'bye'&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First extraction method &lt;code&gt;fetch_all_by_key&lt;/code&gt; , the purpose of this method is to extract all the elements with the same key (for example getting a list of similar objects in a response):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;fetch_all_by_key&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;element: &lt;/span&gt;&lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;key: &lt;/span&gt;&lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;container: &lt;/span&gt;&lt;span class="p"&gt;[])&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;element&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;is_a?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;element&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;fetch_all_by_key&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;element: &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;key: &lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;container: &lt;/span&gt;&lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;elsif&lt;/span&gt; &lt;span class="n"&gt;element&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;is_a?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Hash&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;container&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;element&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;element&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;nil?&lt;/span&gt;
    &lt;span class="n"&gt;element&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each_pair&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;fetch_all_by_key&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;element: &lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;key: &lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;container: &lt;/span&gt;&lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="n"&gt;container&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Usage:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;fetch_all_by_key&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;element: &lt;/span&gt;&lt;span class="n"&gt;input_data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;key: :q&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="ss"&gt;:z&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="ss"&gt;:first_name&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"hello"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                 &lt;span class="ss"&gt;:last_name&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"bye"&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;


&lt;span class="n"&gt;fetch_all_by_key&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;element: &lt;/span&gt;&lt;span class="n"&gt;input_data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;key: :z&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="ss"&gt;:first_name&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"hello"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="ss"&gt;:last_name&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"world"&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="ss"&gt;:first_name&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"hello"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="ss"&gt;:last_name&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"bye"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The next method, is basically the same as the previous one, but will only fetch the first element which fits our requirement (when you care only about getting any element that fits your key):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;deep_fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;element: &lt;/span&gt;&lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;key: &lt;/span&gt;&lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;ret_value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tmp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;element&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;is_a?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;element&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="n"&gt;tmp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;deep_fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;element: &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;key: &lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;break&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;nil?&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;elsif&lt;/span&gt; &lt;span class="n"&gt;element&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;is_a?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Hash&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;element&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;has_key?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;tmp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;element&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
      &lt;span class="n"&gt;element&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each_pair&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
        &lt;span class="n"&gt;tmp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;deep_fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;element: &lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;key: &lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;break&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;nil?&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="n"&gt;ret_value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tmp&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;nil?&lt;/span&gt;
  &lt;span class="n"&gt;ret_value&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;deep_fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;element: &lt;/span&gt;&lt;span class="n"&gt;input_data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;key: :q&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="ss"&gt;:z&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="ss"&gt;:first_name&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"hello"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="ss"&gt;:last_name&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"bye"&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;

 &lt;span class="n"&gt;deep_fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;element: &lt;/span&gt;&lt;span class="n"&gt;input_data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;key: :z&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="ss"&gt;:first_name&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"hello"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="ss"&gt;:last_name&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"world"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="mf"&gt;2.6&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;096&lt;/span&gt; 

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The last method uses the previous method to enforce order (sometimes the same key can appear in two different hierarchical paths hence you want to have more control over what you're fetching):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;multi_deep_fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;element: &lt;/span&gt;&lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;keys: &lt;/span&gt;&lt;span class="p"&gt;[])&lt;/span&gt;
  &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;shift&lt;/span&gt;
    &lt;span class="n"&gt;element&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;deep_fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;element: &lt;/span&gt;&lt;span class="n"&gt;element&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;key: &lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="n"&gt;element&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;


&lt;span class="n"&gt;multi_deep_fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;element: &lt;/span&gt;&lt;span class="n"&gt;input_data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;keys: &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:q&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="ss"&gt;:z&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="ss"&gt;:first_name&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"hello"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="ss"&gt;:last_name&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"bye"&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;



 &lt;span class="n"&gt;multi_deep_fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;element: &lt;/span&gt;&lt;span class="n"&gt;input_data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;keys: &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:z&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="kp"&gt;nil&lt;/span&gt;

 &lt;span class="n"&gt;multi_deep_fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;element: &lt;/span&gt;&lt;span class="n"&gt;input_data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;keys: &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:z&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="ss"&gt;:first_name&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"hello"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="ss"&gt;:last_name&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"world"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;multi_deep_fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;element: &lt;/span&gt;&lt;span class="n"&gt;input_data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;keys: &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:q&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:z&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="ss"&gt;:first_name&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"hello"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="ss"&gt;:last_name&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"bye"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>ruby</category>
      <category>rails</category>
    </item>
  </channel>
</rss>
