<?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>DEV Community: pineapples</title>
    <description>The latest articles on DEV Community by pineapples (@pineapples).</description>
    <link>https://dev.to/pineapples</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%2F631758%2Fb4d6986f-dd4d-4533-934e-43ca96d5f41c.png</url>
      <title>DEV Community: pineapples</title>
      <link>https://dev.to/pineapples</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/pineapples"/>
    <language>en</language>
    <item>
      <title>Understanding Leetcode #15 3Sum</title>
      <dc:creator>pineapples</dc:creator>
      <pubDate>Sat, 19 Apr 2025 16:49:45 +0000</pubDate>
      <link>https://dev.to/pineapples/understanding-leetcode-15-3sum-4cj8</link>
      <guid>https://dev.to/pineapples/understanding-leetcode-15-3sum-4cj8</guid>
      <description>&lt;p&gt;Leetcode # &lt;a href="https://leetcode.com/problems/3sum/description/" rel="noopener noreferrer"&gt;15. 3Sum&lt;/a&gt; provides an unsorted list of integers and asks that you find all unique triplets from that list that add to a target number, in this case zero (0). A brute force approach would be to use three nested &lt;code&gt;for&lt;/code&gt; loops, reaching a runtime complexity of O(n^3) in order to find all triplets. However, building on two earlier Leetcode "sum" problems, &lt;a href="https://leetcode.com/problems/two-sum/" rel="noopener noreferrer"&gt;1. Two Sum&lt;/a&gt; and &lt;a href="https://leetcode.com/problems/two-sum-ii-input-array-is-sorted/description/" rel="noopener noreferrer"&gt;167. Two Sum II - Input Array Is Sorted&lt;/a&gt; (TwoSum Sorted for the rest of this blog) it is possible to implement an O(n^2) approach.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hints
&lt;/h2&gt;

&lt;p&gt;There are two big hints to this problem, as mentioned on Leetcode, that I've paraphrased below:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Can we "fix" one number &lt;code&gt;x&lt;/code&gt; and then traverse the rest of the array to find all combos &lt;code&gt;y&lt;/code&gt; and &lt;code&gt;z&lt;/code&gt; so that &lt;code&gt;x + y + z = 0&lt;/code&gt;? This makes the problem much more similar to TwoSum.&lt;/li&gt;
&lt;li&gt;Can we modify the input array so that search is faster?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The answer is yes! If we sort our array in ascending order we can fix one number for each round and then implement a take on TwoSum Sorted to find all remaining members of each triplet for that number. &lt;/p&gt;

&lt;h2&gt;
  
  
  Runtime
&lt;/h2&gt;

&lt;p&gt;In this case we will target a runtime complexity of O(n^2), which makes the addition of sorting at the beginning "free". More specifically, our target runtime is now O(n^2) + O(nlogn), but in Big O notation the smaller added chunks of runtime will fall away, leaving us with O(n^2).&lt;/p&gt;

&lt;p&gt;Now with sorting out of the way, we can approach this problem similarly to the sorted TwoSum problem and use two pointers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Outer Loop
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The gist
&lt;/h3&gt;

&lt;p&gt;If we "fix" one number &lt;code&gt;x&lt;/code&gt;, we can then scan the array once for each &lt;code&gt;x&lt;/code&gt; using the two pointer approach from TwoSum Sorted to find all possible &lt;code&gt;y&lt;/code&gt; and &lt;code&gt;z&lt;/code&gt; combos such that &lt;code&gt;x + y + z = 0&lt;/code&gt;. See note &lt;em&gt;(a)&lt;/em&gt; below for progressing through the outer loop.&lt;/p&gt;

&lt;h2&gt;
  
  
  Inner Loop:
&lt;/h2&gt;

&lt;p&gt;For each &lt;code&gt;x&lt;/code&gt;, we will use a &lt;code&gt;low&lt;/code&gt; and &lt;code&gt;high&lt;/code&gt; pointer to look for potential options for &lt;code&gt;y&lt;/code&gt; and &lt;code&gt;z&lt;/code&gt; respectively. We will set our &lt;code&gt;low&lt;/code&gt; pointer to &lt;code&gt;x + 1&lt;/code&gt; and our &lt;code&gt;high&lt;/code&gt; pointer to the last element of the array (&lt;code&gt;nums.length - 1&lt;/code&gt;). &lt;/p&gt;

&lt;p&gt;Now we are simply implementing the two pointer approach from TwoSum Sorted. There are two ways to conceptualize what our new TwoSum Sorted approach is seeking:&lt;br&gt;
   &lt;strong&gt;Option 1)&lt;/strong&gt; find the numbers y and z such that &lt;code&gt;x + y + z = 0&lt;/code&gt;&lt;br&gt;
   &lt;strong&gt;Option 2)&lt;/strong&gt; find the numbers y and z such that &lt;code&gt;y + z = x * -1&lt;/code&gt;.&lt;br&gt;
I prefer Option 1 so that is shown in the code below.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Gist
&lt;/h3&gt;

&lt;p&gt;At each step of TwoSum Sorted ask:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Does the sum of &lt;code&gt;x + y + z&lt;/code&gt; equal 0? If yes, we've found a valid answer so add this triplet to the result. Then iterate both &lt;code&gt;low&lt;/code&gt; (increase with &lt;code&gt;low++&lt;/code&gt;) and &lt;code&gt;high&lt;/code&gt; (decrease with &lt;code&gt;high--&lt;/code&gt;). See note &lt;em&gt;(b)&lt;/em&gt; below.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Alternately, if this sum does not equal &lt;code&gt;0&lt;/code&gt;, we need to figure out which pointer to move:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If the sum is less than the target (&lt;code&gt;0&lt;/code&gt;), then we know our current combination of numbers is too low. Therefore, we need to increase the numbers involved. Increase the bottom pointer with &lt;code&gt;low++&lt;/code&gt; (see note &lt;em&gt;(b)&lt;/em&gt; below).&lt;/li&gt;
&lt;li&gt;If the sum is greater than the target, the opposite is true and we need to decrease the values involved. Decrease the high pointer with &lt;code&gt;high--&lt;/code&gt; (see note c below).&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;We will follow this process until we've traversed our current section of the array (x + 1 to end) and save all valid triplets in a results array. Then progress to the next element in the outer loop and repeat, continuing until we've reached the end of the array or gone above &lt;code&gt;0&lt;/code&gt; (see note &lt;em&gt;(d)&lt;/em&gt; below).&lt;/p&gt;

&lt;h2&gt;
  
  
  Notes
&lt;/h2&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;a) In our outer `for` loop, skip any duplicate numbers.
b) Like in (a), when we find a valid triplet and we increase `low`, skip any duplicate numbers.
c) We will check all `high` values every time. As we are validating uniqueness on `x` and `y`, we should include duplicates for `z`. This ensures that we find all valid triplet combos while skipping duplicates.
d) In our outer loop, stop once we've gone above `0`. As our array is ordered, if `x` is 1, that means any potential `y` or `z` will be at least `1`. It is not possible for `1 + 1 + 1` (or any larger combination of numbers) to equal `0` so we know we are done at that point.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Code:
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;threeSum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;

    &lt;span class="nx"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;b&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;let&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;nums&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nums&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="o"&gt;&amp;lt;=&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="k"&gt;if &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="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;nums&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="o"&gt;!==&lt;/span&gt; &lt;span class="nx"&gt;nums&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="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="nf"&gt;twoSumII&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nums&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="nx"&gt;results&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="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;results&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;twoSumII&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nums&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="nx"&gt;results&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;lo&lt;/span&gt; &lt;span class="o"&gt;=&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;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;hi&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&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;lo&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;hi&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;nums&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="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;lo&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;hi&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;&amp;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="nx"&gt;hi&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="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&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="nx"&gt;lo&lt;/span&gt;&lt;span class="o"&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;nums&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;lo&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;lo&lt;/span&gt; &lt;span class="o"&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="nx"&gt;lo&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="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;results&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nx"&gt;nums&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="nx"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;lo&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;hi&lt;/span&gt;&lt;span class="p"&gt;]]);&lt;/span&gt;

            &lt;span class="nx"&gt;lo&lt;/span&gt;&lt;span class="o"&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;nums&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;lo&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;lo&lt;/span&gt; &lt;span class="o"&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="nx"&gt;lo&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;hi&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="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>leetcode</category>
      <category>algorithms</category>
      <category>javascript</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Writing a 'Median of Three' Pivot Helper for QuickSort</title>
      <dc:creator>pineapples</dc:creator>
      <pubDate>Fri, 09 Dec 2022 21:39:59 +0000</pubDate>
      <link>https://dev.to/pineapples/writing-a-median-of-three-pivot-helper-for-quicksort-289m</link>
      <guid>https://dev.to/pineapples/writing-a-median-of-three-pivot-helper-for-quicksort-289m</guid>
      <description>&lt;p&gt;QuickSort Basics&lt;br&gt;
The Pivot&lt;br&gt;
Median Value&lt;br&gt;
Update Array Around Pivot&lt;/p&gt;
&lt;h2&gt;
  
  
  QuickSort Basics &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;QuickSort is an algorithm for sorting an array based on a pivot point in the array. To see a 3 minute visual on how QuickSort works, check out this &lt;a href="https://www.youtube.com/watch?v=XE4VP_8Y0BU" rel="noopener noreferrer"&gt;video&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To implement QuickSort (or skip ahead to the pivot if you prefer): &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Choose a pivot from the array (more on how to choose a pivot below)&lt;/li&gt;
&lt;li&gt;The pivot function should also update the array in place by moving 

&lt;ul&gt;
&lt;li&gt;all elements smaller than the pivot value to the left of the pivot and &lt;/li&gt;
&lt;li&gt;all elements greater than (or equal to) the pivot to its right.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Once the elements on either side of the pivot are on their correct side, the pivot value itself is correctly placed into its final location in the sorted array.&lt;/li&gt;
&lt;li&gt;Since the pivot value is now correct, you can disregard it and move on to sorting the elements on either side of it: 

&lt;ul&gt;
&lt;li&gt;Do this by recursively calling QuickSort again on both the left side of the pivot and the right side of the pivot.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The code for the outer QuickSort function might look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;numberCompare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&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;a&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;b&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="nf"&gt;quickSort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;comparator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;numberCompare&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;start&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;end&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;start&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;end&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;iPivot&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;pivot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;comparator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;start&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;end&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 

        &lt;span class="nf"&gt;quickSort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;comparator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;start&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;iPivot&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nf"&gt;quickSort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;comparator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;iPivot&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;end&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;arr&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;&lt;strong&gt;Some code notes:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;numberCompare()&lt;/code&gt;: We provide a default comparator function (&lt;code&gt;numberCompare&lt;/code&gt;) for sorting numbers in ascending order. To sort the array differently (perhaps alphabetically for strings, or in descending order), supply a different comparator function when invoking &lt;code&gt;quickSort&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;pivot()&lt;/code&gt;: This helper function will handle the following steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;select a value from the array as the pivot&lt;/li&gt;
&lt;li&gt;mutate the array in place so values less than the pivot are moved to its left and values greater than/equal to the pivot are moved to its right&lt;/li&gt;
&lt;li&gt;return the index of the pivot value's final location (after array mutation is complete), allowing &lt;code&gt;quickSort&lt;/code&gt; to be called again on each side of the pivot index&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  The Pivot &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;With the QuickSort basics out of the way, let's talk about the pivot. Technically, you can choose any value in the array as the pivot. However, some options can result in less optimal runtimes.&lt;/p&gt;
&lt;h3&gt;
  
  
  Naive Options:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Always choose the first element of the current array subsection. &lt;/li&gt;
&lt;li&gt;Always choose the last element of the current array subsection.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Both of these will work and can be a bit simpler to implement. However, they run the risk of worse time complexity. On a sorted or nearly sorted array, these will both have O(n^2) runtime as each iteration of sorting will have to sort all of the remaining elements. &lt;/p&gt;
&lt;h3&gt;
  
  
  Pivot Improvements:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Random value from the array as pivot&lt;/li&gt;
&lt;li&gt;Median Value of the array&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These options can improve the runtime and increase the likelihood of an O(n log n) runtime, including for sorted arrays. We'll discuss using a median value.&lt;/p&gt;
&lt;h2&gt;
  
  
  Median Value &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Median refers to the middle value in a sorted set of data, with an equal number of items on either side of it. Ideally, every time we run QuickSort, we want to pivot around the median value of our current array subsection, rather than skewing the implementation towards the highest or lowest values.&lt;/p&gt;

&lt;p&gt;Unfortunately, we don't actually know the median value because the array is not yet sorted. Instead we can use the "Median of Three" Strategy.&lt;/p&gt;
&lt;h3&gt;
  
  
  Median of Three &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;To implement the  "Median of Three" strategy, select the first, last, and middle elements from your current array (or array portion as the recursive calls begin). Take the median (middle) value of those three elements to use for the current pivot.&lt;/p&gt;

&lt;p&gt;The code to find the median might look something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;bigger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;b&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;a&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;b&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="nf"&gt;getMedianPivotIdx&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;start&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;end&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;floor&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;start&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;end&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;iBiggest&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;bigger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;start&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;bigger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;mid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;end&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;iBiggest&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;start&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;bigger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;mid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;end&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;iBiggest&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;end&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;bigger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;start&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;mid&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;bigger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;start&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;end&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;This function will return the index of the median value between the start, end, and middle values, allowing you to use that for a pivot.&lt;/p&gt;

&lt;h2&gt;
  
  
  Update Array Around Pivot &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;With the pivot selected, implement the rest of the pivot function: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;find the correct location for the pivot by moving

&lt;ul&gt;
&lt;li&gt;all values less than the pivot value to its left and&lt;/li&gt;
&lt;li&gt;all values greater than (or equal to) the pivot to its right.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;One important implementation detail when actually writing this pivot code is to make sure you move the pivot value out of the way before comparing the rest of the values. (In the code below, you'll see we swap the pivot and the end values before iterating through the array to move elements to their proper side of the pivot.) &lt;/p&gt;

&lt;p&gt;The full pivot helper might look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;swap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;idxA&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;idxB&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="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;idxA&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;idxB&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="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;idxB&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;idxA&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="nf"&gt;pivot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;comparator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;numberCompare&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;start&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;end&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;iPivotStart&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getMedianPivotIdx&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;start&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;end&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;pivotVal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;iPivotStart&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;iPivotTarget&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;start&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nf"&gt;swap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;iPivotStart&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;end&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;//swap the end and the pivot before iterating through array to update elements in place&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;iPivotTemp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;end&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;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;start&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;iPivotTemp&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="c1"&gt;//update array in place by moving smaller elements to the front of the array&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;curr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;arr&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;comparator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;curr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;pivotVal&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&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="nf"&gt;swap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arr&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="nx"&gt;iPivotTarget&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;iPivotTarget&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// iPivotTarget is incremented with each swap to provide the correct location for the current swap and count the number of swaps. The final pivot index should be equal to the number of swaps.&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;swap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;iPivotTemp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;iPivotTarget&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// after moving all smaller elements to the front of the array, swap the pivot with the first element that is larger than the pivot&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;iPivotTarget&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// return the final index of the pivot&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>tutorial</category>
      <category>sorting</category>
    </item>
    <item>
      <title>Why a Hash Table is a Performant Data Structure</title>
      <dc:creator>pineapples</dc:creator>
      <pubDate>Fri, 02 Dec 2022 23:35:02 +0000</pubDate>
      <link>https://dev.to/pineapples/why-a-hash-table-is-a-performant-data-structure-1abb</link>
      <guid>https://dev.to/pineapples/why-a-hash-table-is-a-performant-data-structure-1abb</guid>
      <description>&lt;p&gt;A hash table is type of key-value data store. Nearly every coding language includes some form of hash table by default. In Ruby, this is called a "hash", in python a "dictionary", in JavaScript an "object" or "map". &lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding the Basics
&lt;/h2&gt;

&lt;p&gt;Typically, a hash table is implemented with an associative array where each index in the array provides a slot for storing data, in this case key-value pairs. The basic operations we'll discuss here are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Insertion:&lt;/strong&gt; adding key-value pairs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Access/Search:&lt;/strong&gt; finding a value in the store based on a key&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deletion:&lt;/strong&gt; deleting a key-value pair&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Hash Function
&lt;/h2&gt;

&lt;p&gt;All of these operations (insertion, removal, and access) depend on a well written hash function. On a high level, a hash function takes an input of any size and converts that to an output of a fixed size. The output of the hash function is used as the index in the associative array for storing the data.&lt;/p&gt;

&lt;p&gt;For a hash table, the hash function must do the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Convert the input (key) to an index that exists in the associative array&lt;/li&gt;
&lt;li&gt;Distribute hashed values evenly to reduce collisions&lt;/li&gt;
&lt;li&gt;Perform in constant time&lt;/li&gt;
&lt;li&gt;Be deterministic - always convert the same input to the same output&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Handling Collisions
&lt;/h2&gt;

&lt;p&gt;A collision results when the hash of multiple keys result in the same output (or index in our associative array).&lt;/p&gt;

&lt;p&gt;There are multiple solutions for handling collisions. One solution is called &lt;strong&gt;Separate Chaining&lt;/strong&gt;, where we use a second data structure at each index,  perhaps an array or linked list, to list all pairs whose key is hashed to that index. In order to perform any of our basic functions, we first iterate through the list at that index to check for the key. &lt;/p&gt;

&lt;p&gt;If every hashed key "collides" or results in the same index in the associative array, we end up performing an O(N) check for each function. With minimal collisions however, we typically will have such few items at each index that each operation is just O(1).&lt;/p&gt;

&lt;p&gt;The best hash tables, such as the built-in hash tables provided by coding languages, minimize these collisions in order to ensure the best time complexity for standard operations. A well written hash table ensures that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It allocates a large enough associative array to provide many slots for data .&lt;/li&gt;
&lt;li&gt;It uses a high quality hash function to evenly distribute keys within the associative array.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Using the Hash Table
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Insertion
&lt;/h3&gt;

&lt;p&gt;To add an element, the key is hashed to get an index in the associative array. If the key already exists in the array at that index, the existing key's value is updated. Otherwise, the new key-value pair is pushed onto the inner array.&lt;/p&gt;

&lt;h3&gt;
  
  
  Access/Search (By Key)
&lt;/h3&gt;

&lt;p&gt;Getting the value of a key follows a similar process to insertion. First, the key is hashed to get the index. That index in the array is then visited. If the key is found at that index, the value of the key is returned. If the key is not found, it does not exist and some falsey signifier is returned.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; It is also possible to search a hash table by value. However, this is not an optimal use of a hash table, and the Big O will be linear or O(N).&lt;/p&gt;

&lt;h3&gt;
  
  
  Removal
&lt;/h3&gt;

&lt;p&gt;Again, the key is hashed to get the index where it is stored in the associative array. The array at that index is searched. If the key is found, the key-value pair is removed. If it's not found, nothing else happens.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Benefits of a Hash Table:
&lt;/h2&gt;

&lt;p&gt;A hash table is optimized for insertion, removal, and searching based on the key. A well written hash table has constant (O(1)) "amortized" time for these operations. Thus, this can be an excellent choice for storing unordered data. It provides much faster access than an array, and is virtually guaranteed to be faster that an array for insertion or deletion, when the data's index in an array is unknown.&lt;/p&gt;

</description>
      <category>watercooler</category>
    </item>
    <item>
      <title>Understanding the Different Strategies of Depth First Search Tree Traversal</title>
      <dc:creator>pineapples</dc:creator>
      <pubDate>Tue, 29 Nov 2022 22:17:28 +0000</pubDate>
      <link>https://dev.to/pineapples/understanding-the-different-strategies-of-depth-first-search-tree-traversal-3bn3</link>
      <guid>https://dev.to/pineapples/understanding-the-different-strategies-of-depth-first-search-tree-traversal-3bn3</guid>
      <description>&lt;p&gt;Depth First Search (DFS) tree traversal can be performed with any of the following strategies: "in-order", "post-order", and "pre-order". What's the difference? The difference is actually quite simple - it is simply the order in which you visit the node compared to when you traverse the children of the node. &lt;/p&gt;

&lt;h2&gt;
  
  
  The Basics
&lt;/h2&gt;

&lt;p&gt;To better understand what this means, let's talk about the basics of tree traversal. For simplicity, we'll assume we're only working with binary trees where each node can have at most two children, a left child and a right child.&lt;/p&gt;

&lt;p&gt;For each node of the binary tree, there are three steps to complete:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;traverse the left subtree&lt;/li&gt;
&lt;li&gt;traverse the right subtree&lt;/li&gt;
&lt;li&gt;do something with the node itself - here we'll record it's value&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So with these three steps established, we can place them in their correct order for each DFS strategy:&lt;/p&gt;

&lt;h3&gt;
  
  
  Pre-order:
&lt;/h3&gt;

&lt;p&gt;In pre-order, we first process the node:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Do something: record the node's value&lt;/li&gt;
&lt;li&gt;Traverse the left&lt;/li&gt;
&lt;li&gt;Traverse the right&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Post-order:
&lt;/h3&gt;

&lt;p&gt;In post-order, we process the node last:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Traverse the left&lt;/li&gt;
&lt;li&gt;Traverse the right&lt;/li&gt;
&lt;li&gt;Do something: record the node's value&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  In-order:
&lt;/h3&gt;

&lt;p&gt;For in-order, we'll process the node in between traversing each side:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Traverse the left&lt;/li&gt;
&lt;li&gt;Do something: record the node's value&lt;/li&gt;
&lt;li&gt;Traverse the right&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;As we can see from the steps above, we do the exact same thing in each strategy, just in a slightly different order. This means we can use the same lines of code for each method. We'll just need to make a slight alteration in the order.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Code
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Tree Structure
&lt;/h3&gt;

&lt;p&gt;We'll assume we have a Binary Tree class that looks something like this Binary Search Tree:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Node&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;val&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;left&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;right&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&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;class&lt;/span&gt; &lt;span class="nc"&gt;BinarySearchTree&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;root&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newNode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;root&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;root&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;newNode&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;curr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;root&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="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;curr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;val&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;curr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;left&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nx"&gt;curr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;left&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;newNode&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
          &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="nx"&gt;curr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;curr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;left&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;curr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;val&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;curr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;right&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nx"&gt;curr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;right&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;newNode&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
          &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="nx"&gt;curr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;curr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;right&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;  &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
         &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Depth First Search Pseudo Code
&lt;/h3&gt;

&lt;p&gt;We will write a function that accepts a node (the root of a tree on the first pass) and returns an array of all the values in that tree, after visiting all of the nodes once. Here, we'll use a recursive strategy.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Our function will create an array, &lt;code&gt;visited&lt;/code&gt;, to record the values of visited nodes. &lt;/li&gt;
&lt;li&gt;Our base case will check if the node is null. If so, we'll return the empty array. &lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Otherwise we need to perform our three steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;add the value of the node to the &lt;code&gt;visited&lt;/code&gt; array&lt;/li&gt;
&lt;li&gt;Recursively call our function again, passing in the left child as the node and concatenating the return value of this function call to the &lt;code&gt;visited&lt;/code&gt; array&lt;/li&gt;
&lt;li&gt;Recursively call our function again, passing in the right child as the node and concatenating the return value of this function call to the &lt;code&gt;visited&lt;/code&gt; array&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;p&gt;After visiting all nodes in the tree, the &lt;code&gt;visited&lt;/code&gt; array will be filled with the values of each node. &lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Finally, we will return &lt;code&gt;visited&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Depth First Search Function
&lt;/h3&gt;

&lt;p&gt;For &lt;strong&gt;Pre Order&lt;/strong&gt; (visit the node first) this looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;dfsPreOrder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;visited&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;node&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;visited&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;//base case&lt;/span&gt;

  &lt;span class="nx"&gt;visited&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;//1. visit node&lt;/span&gt;
  &lt;span class="nx"&gt;visited&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;visited&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;concat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;dfsPreOrder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;left&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;//2. traverse left&lt;/span&gt;
  &lt;span class="nx"&gt;visited&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;visited&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;concat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;dfsPreOrder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;right&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;//2. traverse right&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;visited&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;For &lt;strong&gt;Post Order&lt;/strong&gt; (visit the node last) this looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;dfsPostOrder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;visited&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;node&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;visited&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;//base case&lt;/span&gt;

  &lt;span class="nx"&gt;visited&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;visited&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;concat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;dfsPostOrder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;left&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;//1. traverse left&lt;/span&gt;
  &lt;span class="nx"&gt;visited&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;visited&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;concat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;dfsPostOrder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;right&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;//2. traverse right&lt;/span&gt;
  &lt;span class="nx"&gt;visited&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;//3. visit node&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;visited&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;For &lt;strong&gt;In Order&lt;/strong&gt; (visit the node in the middle) this looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;dfsInOrder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;visited&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;node&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;visited&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;//base case&lt;/span&gt;

  &lt;span class="nx"&gt;visited&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;visited&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;concat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;dfsInOrder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;left&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;//1. traverse left&lt;/span&gt;
  &lt;span class="nx"&gt;visited&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;//2. visit node&lt;/span&gt;
  &lt;span class="nx"&gt;visited&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;visited&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;concat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;dfsInOrder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;right&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;//3. traverse right&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;visited&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>graphql</category>
      <category>typescript</category>
      <category>discuss</category>
      <category>github</category>
    </item>
    <item>
      <title>Implement a Stack with a Singly Linked List</title>
      <dc:creator>pineapples</dc:creator>
      <pubDate>Tue, 29 Nov 2022 04:23:48 +0000</pubDate>
      <link>https://dev.to/pineapples/implement-a-stack-with-a-singly-linked-list-gjg</link>
      <guid>https://dev.to/pineapples/implement-a-stack-with-a-singly-linked-list-gjg</guid>
      <description>&lt;h2&gt;
  
  
  First In, Last Out
&lt;/h2&gt;

&lt;p&gt;A stack is a data structure that follows the First In, Last Out (FILO) principal. You can think of this like a stack of plates. As you put plates away, each one goes on top of the one before. As you pull them out, you take the plate from the top of the stack, which is the one that was most recently added. Stacks are useful in many instances. For example, the browser's call stack is a stack. The ability to undo and redo (like in PhotoShop) is also commonly implemented using stacks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Native Data Structures
&lt;/h2&gt;

&lt;p&gt;JavaScript does not include a native stack structure. You can use the built-in JavaScript array to mock a stack, relying on its &lt;code&gt;push&lt;/code&gt; and &lt;code&gt;pop&lt;/code&gt; methods for O(1) insertion and removal. However, there can be drawbacks to this method. Using an array requires extra memory for storing indices for each element. There is also the possibility that the location in memory where your array is stored runs out of space, requiring full re-indexing of the entire array in order to add one element.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implement with a Singly Linked List
&lt;/h2&gt;

&lt;p&gt;In order to implement a stack with a linked list, you can create a &lt;code&gt;Node&lt;/code&gt; class where each element of the stack is a node. Each node should have a value property and a pointer to the next node:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Node&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;val&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;next&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&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;Next, you can create a &lt;code&gt;Stack&lt;/code&gt; class, which is simply a Linked List that we've named Stack. In this example, we'll use properties of head and size:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Stack&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;head&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;size&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="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Required Methods
&lt;/h3&gt;

&lt;p&gt;The two most important methods to add to our Stack are &lt;code&gt;push&lt;/code&gt; and &lt;code&gt;pop&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Push
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;push&lt;/code&gt; accepts a value as an argument, and adds that value to the top of the stack. In practice that means, creating a new node using the value passed in, updating the head value on our stack to point to the new node, and incrementing the stack's size:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Stack&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;

  &lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newNode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;newNode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;next&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;head&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;head&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;newNode&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&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;h4&gt;
  
  
  Pop
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;pop&lt;/code&gt; is nearly the inverse of &lt;code&gt;push&lt;/code&gt;. It will remove the most recently added node in our stack and return it. In this case, that means removing the existing head node, updating that head's next node to become the new head node, and decrementing the size. We'll also remove the old head's pointer into the list to avoid any accidental look-up abilities:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Stack&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;

  &lt;span class="nf"&gt;pop&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;head&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;oldHead&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;head&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;head&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;oldHead&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;oldHead&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;next&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt;&lt;span class="o"&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;oldHead&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;h3&gt;
  
  
  Additional Methods
&lt;/h3&gt;

&lt;p&gt;Some other methods that are commonly added include &lt;code&gt;peek&lt;/code&gt;, &lt;code&gt;isEmpty&lt;/code&gt;, and &lt;code&gt;size&lt;/code&gt;. &lt;/p&gt;

&lt;h4&gt;
  
  
  Peek
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;peek&lt;/code&gt; returns the top element on the stack, without removing it, allowing us to "peek" into the stack:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Stack&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;

  &lt;span class="nf"&gt;peek&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;head&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;h4&gt;
  
  
  isEmpty
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;isEmpty&lt;/code&gt; returns a boolean - true if the stack is empty or false if not:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Stack&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;

  &lt;span class="nf"&gt;isEmpty&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="o"&gt;!!&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;size&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;h4&gt;
  
  
  size
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;size&lt;/code&gt; returns the size of the stack:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Stack&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;

  &lt;span class="nf"&gt;size&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;size&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>emptystring</category>
    </item>
    <item>
      <title>Two Ways to Check an Object for Keys</title>
      <dc:creator>pineapples</dc:creator>
      <pubDate>Sun, 27 Nov 2022 18:08:50 +0000</pubDate>
      <link>https://dev.to/pineapples/two-ways-to-check-an-object-for-keys-h2m</link>
      <guid>https://dev.to/pineapples/two-ways-to-check-an-object-for-keys-h2m</guid>
      <description>&lt;h2&gt;
  
  
  The Old Way
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;Object.prototype.hasOwnProperty()&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty" rel="noopener noreferrer"&gt;&lt;code&gt;Object.prototype.hasOwnProperty()&lt;/code&gt;&lt;/a&gt; is called on an object with the key (or property) for which you are checking passed in as an argument. This returns true if the property exists or false if not. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; this only checks for declared or &lt;em&gt;own&lt;/em&gt; properties. Inherited properties will also return false.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;obj1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Sam&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt;

&lt;span class="nx"&gt;obj1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hasOwnProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;span class="c1"&gt;// =&amp;gt; true&lt;/span&gt;

&lt;span class="nx"&gt;obj1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hasOwnProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;address&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// =&amp;gt; false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Gotchas
&lt;/h3&gt;

&lt;p&gt;One drawback to this method is that it is not accessible on an object created with &lt;code&gt;Object.create(null)&lt;/code&gt; and will error in that case: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fijvmncwxq2cbqnun7nug.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fijvmncwxq2cbqnun7nug.png" alt="Error calling  raw `.hasOwnProperty` endraw  on object created with  raw `Object.create(null` endraw " width="800" height="220"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Recommended Way
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;Object.hasOwn()&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Per MDN, &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwn" rel="noopener noreferrer"&gt;&lt;code&gt;Object.hasOwn()&lt;/code&gt;&lt;/a&gt; is a replacement for the previously existing &lt;code&gt;.hasOwnProperty&lt;/code&gt; method. It is nearly identical to &lt;code&gt;.hasOwnProperty&lt;/code&gt; - it returns true if the object has the property as an &lt;em&gt;own&lt;/em&gt; property and false for inherited properties as well as properties that do not exist.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;obj2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Tim&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hasOwn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// =&amp;gt; true&lt;/span&gt;

&lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hasOwn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;address&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// =&amp;gt; false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, &lt;code&gt;.hasOwn&lt;/code&gt; also works on objects created with &lt;code&gt;Object.create(null)&lt;/code&gt; and therefore is recommended for use on all browsers that support it:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftjphh7j6k969z9x5ec42.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftjphh7j6k969z9x5ec42.png" alt="Successful use of  raw `hasOwn` endraw  method on object created by Object.create(null)" width="800" height="212"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>object</category>
    </item>
    <item>
      <title>Dynamically Create an Array of Arrays</title>
      <dc:creator>pineapples</dc:creator>
      <pubDate>Sun, 27 Nov 2022 03:51:57 +0000</pubDate>
      <link>https://dev.to/pineapples/dynamically-create-an-array-of-arrays-3gd1</link>
      <guid>https://dev.to/pineapples/dynamically-create-an-array-of-arrays-3gd1</guid>
      <description>&lt;h2&gt;
  
  
  The Reason
&lt;/h2&gt;

&lt;p&gt;In a recent algorithm challenge, I wanted to create an iterable collection of ten "buckets" for grouping data. In practice, this meant creating an array of arrays like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[[], [], [], [], [], [], [], [], [], []]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What Did Not Work
&lt;/h2&gt;

&lt;p&gt;Rather than hard code each set of arrays, I wanted to create this dynamically. My first attempt (from memory and a cursory skim of the MDN docs), was to use the Array constructor with the &lt;code&gt;.fill&lt;/code&gt; method chained on:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const arr = new Array(10).fill([]);
console.log(arr);
// =&amp;gt; [[], [], [], [], [], [], [], [], [], []];
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At first glance, this seemed to work. Console logging my new &lt;code&gt;arr&lt;/code&gt; revealed an array containing 10 empty arrays, so I continued solving the algorithm. &lt;/p&gt;

&lt;p&gt;As soon as I began populating the inner arrays (the buckets), I noticed that there was an issue - adding an element to one "bucket", for example at index 5, updated EVERY bucket to match, rather than only the intended bucket:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;arr[5].push("hello");
console.log(arr);
// =&amp;gt; [["hello"], ["hello"], ["hello"], ["hello"], ["hello"], ["hello"], ["hello"], ["hello"], ["hello"], ["hello"]];
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Returning to the MDN docs for &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/fill" rel="noopener noreferrer"&gt;&lt;code&gt;Array.prototype.fill&lt;/code&gt;&lt;/a&gt;, the issue became clear:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frp68bk3o292o4xuk2p6h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frp68bk3o292o4xuk2p6h.png" alt="Screenshot of MDN docs for fill method" width="800" height="196"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As arrays are a type of object, each of my array buckets were actually referencing the same object in memory. So rather than creating 10 distinct arrays, my array was merely displaying 10 copies of the same array.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;Array.from&lt;/code&gt; to the Rescue
&lt;/h2&gt;

&lt;p&gt;To dynamically create an array of arrays (or other objects), you can instead use the &lt;code&gt;.from&lt;/code&gt; method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const newArr = Array.from({ length: 10 }, () =&amp;gt; []);
console.log(newArr);
// =&amp;gt; [[], [], [], [], [], [], [], [], [], []];
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Per MDN, &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from" rel="noopener noreferrer"&gt;&lt;code&gt;Array.from&lt;/code&gt;&lt;/a&gt; accepts an iterable or "array-like" object as it's first argument, and an optional callback function ("mapFn") for a second argument.&lt;/p&gt;

&lt;p&gt;Here, &lt;code&gt;{length: 10}&lt;/code&gt; is an "array-like" object which will provide the length of the array being created.&lt;/p&gt;

&lt;p&gt;The second argument &lt;code&gt;() =&amp;gt; []&lt;/code&gt; is the "mapFn", which is called for each element and whose return value is used to populate the array.&lt;/p&gt;

&lt;p&gt;Now, pushing an element to the array at index 5, updates only that array, as expected:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;newArr[5].push("hello");
console.log(newArr);
// =&amp;gt; [[], [], [], [], [], ["hello"], [], [], [], []];
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>webdev</category>
      <category>css</category>
      <category>learning</category>
      <category>discuss</category>
    </item>
    <item>
      <title>A Brief Overview of Rails Generators</title>
      <dc:creator>pineapples</dc:creator>
      <pubDate>Fri, 15 Oct 2021 18:32:58 +0000</pubDate>
      <link>https://dev.to/pineapples/a-brief-overview-of-rails-generators-47n8</link>
      <guid>https://dev.to/pineapples/a-brief-overview-of-rails-generators-47n8</guid>
      <description>&lt;p&gt;One of the beautiful things about the Rails framework is the way that it codifies a number of best practices into an easy to get started, customizable, and highly documented tool. Why reinvent the wheel building up a boilerplate app when you can rely on some of the great minds who already did so, and focus your time on your own innovations? Rails generators are just one of the many things that allows Rails to power up great apps in a relatively short timeframe. We'll touch on some basics below.&lt;/p&gt;

&lt;h2&gt;
  
  
  Standard Generators
&lt;/h2&gt;

&lt;p&gt;The basic format of a Rails generator is &lt;code&gt;&amp;lt;rails generate generator-name details...&amp;gt;&lt;/code&gt;. This can also be shortened with the alias for &lt;code&gt;generate&lt;/code&gt;, &lt;code&gt;g&lt;/code&gt;, to &lt;code&gt;&amp;lt;rails g generator-name details....&amp;gt;&lt;/code&gt;. In these examples, I'll use the alias &lt;code&gt;g&lt;/code&gt;, but they can be written either way. For this example, we'll imagine that we are building an application with Book, Author, and Publisher models. &lt;/p&gt;

&lt;h3&gt;
  
  
  Model Generator:
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Format:&lt;/em&gt; &lt;code&gt;&amp;lt;rails g model Modelname&amp;gt;&lt;/code&gt;&lt;br&gt;
&lt;em&gt;Example:&lt;/em&gt; &lt;code&gt;rails g model Book&lt;/code&gt;&lt;br&gt;
This will create an empty migration for the books table, a Book model, plus the test files for the Book model.&lt;/p&gt;

&lt;h3&gt;
  
  
  Migration Generator:
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Format:&lt;/em&gt; &lt;code&gt;&amp;lt;rails g migration camel_case_description_of_migration column_name:data_type&amp;gt;&lt;/code&gt;&lt;br&gt;
&lt;em&gt;Example:&lt;/em&gt; &lt;code&gt;rails g migration add_name_column_to_books name:string&lt;/code&gt;&lt;br&gt;
This will create a fully populated  migration file that looks like:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkfaiusorx7syg2y7wy30.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkfaiusorx7syg2y7wy30.png" alt="Screen Shot 2021-10-08 at 5.39.52 PM" width="800" height="176"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Controller Generator:
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Format:&lt;/em&gt; &lt;code&gt;&amp;lt;rails g controller Pluralname [action action] [options]&amp;gt;&lt;/code&gt;&lt;br&gt;
&lt;em&gt;Example:&lt;/em&gt; &lt;code&gt;rails g controller Books new create show update&lt;/code&gt;&lt;br&gt;
This is a great generator to use in tandem with the Model and Migration generators. This example of the Controller generator will create a BooksController, complete with the boilerplate for actions listed in the generator (new, create, show, update) as well as view files for each of those actions. In addition, this will create routes for the listed actions, plus an associated scss file, and additional tests for the created items&lt;/p&gt;

&lt;h3&gt;
  
  
  Resource Generator:
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Format:&lt;/em&gt; &lt;code&gt;&amp;lt;rails g resource Modelname column_name:data_type&amp;gt;&lt;/code&gt;&lt;br&gt;
&lt;em&gt;Example:&lt;/em&gt; &lt;code&gt;rails g resource Author name:string&lt;/code&gt;&lt;br&gt;
The resource generator builds on the above three controllers while offering some slight variation. It will generate a migration file to create the authors table, complete with any options we passed in, here a name column with a string datatype. This will also generate the Author model, AuthorsController, a view folder for the author related view pages, a helper file, the full authors resource for routes, associated tests, and a scss file.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scaffold Generator:
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Format:&lt;/em&gt; &lt;code&gt;&amp;lt;rails g scaffold Modelname column_name:data_type&amp;gt;&lt;/code&gt;&lt;br&gt;
&lt;em&gt;Example:&lt;/em&gt; &lt;code&gt;rails g scaffold Publisher name:string&lt;/code&gt;&lt;br&gt;
The Scaffold generator is the most robust generator. This builds a complete app according to boilerplate Rails standards. If you are quickly bootstrapping an app and want to follow all the conventions, this can be a great option to get something off the ground very quickly. I won't list all the files this generates, but the &lt;a href="https://guides.rubyonrails.org/v3.2/getting_started.html" rel="noopener noreferrer"&gt;Rails documentation&lt;/a&gt; shows a full list. One note, in most cases you won't be building an app that completely follows conventions so this generator is used less often than other ones.&lt;/p&gt;

&lt;h2&gt;
  
  
  Additional Tools
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Adding references:
&lt;/h3&gt;

&lt;p&gt;One of the great things about using Rails generators is that you can populate most of the details of your &lt;code&gt;belongs_to&lt;/code&gt; relationships via the command line. Rails will also work behind the scenes during database lookups to enforce requirements of these relationships when they are generated in this way. Using our examples above, we can imagine that a book belongs to an author. If we re-create our Book, we can add this relationship in:&lt;br&gt;
&lt;code&gt;rails g resource Book name:string author:references&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Task Generator:
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Format:&lt;/em&gt; &lt;code&gt;&amp;lt;rails g task task_name&amp;gt;&lt;/code&gt;&lt;br&gt;
&lt;em&gt;Example:&lt;/em&gt; &lt;code&gt;rails g task track_books&lt;/code&gt;&lt;br&gt;
This will create a task file located in the &lt;code&gt;tasks&lt;/code&gt; folder (&lt;code&gt;lib/tasks/track_books.rake&lt;/code&gt;) where you can define tasks that you need in your app.&lt;/p&gt;

&lt;h3&gt;
  
  
  Destroy Generator:
&lt;/h3&gt;

&lt;p&gt;This will do the reverse action of the associated generator and completely roll back whatever is included in the description. This full name of this command is &lt;code&gt;destroy&lt;/code&gt;, but it can be aliased as &lt;code&gt;d&lt;/code&gt;.&lt;br&gt;
&lt;em&gt;Format:&lt;/em&gt; &lt;code&gt;&amp;lt;rails d model Name&amp;gt;&lt;/code&gt;&lt;br&gt;
&lt;em&gt;Example:&lt;/em&gt; &lt;code&gt;rails d model Book&lt;/code&gt;&lt;br&gt;
This example rolls back everything that was created with the command &lt;code&gt;rails g model Book&lt;/code&gt;, destroying the associated test files, the Model, and the boilerplate migration.&lt;/p&gt;

&lt;p&gt;I'll leave you with a final benefit to using generators when you can. As much as typing less to create more allows you to save time, generators also offer built in protection against typos and some anti-patterns. The human brain can only remember or see so much. Even while I was typing up this blog post, I was positive I had spelled "codefies" correctly and there was some other reason it had the squiggly line below it. (Turns out it really is "codifies", not "codefies" and an "e" is not an "i"...) So developers are prone to making mistakes. Sometimes those mistakes result in massive debugging efforts, but if you can avoid that, you may as well.&lt;/p&gt;

</description>
      <category>rails</category>
      <category>ruby</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Transparent Background with CSS and GIMP</title>
      <dc:creator>pineapples</dc:creator>
      <pubDate>Tue, 03 Aug 2021 18:10:46 +0000</pubDate>
      <link>https://dev.to/pineapples/transparent-background-with-css-and-gimp-44eh</link>
      <guid>https://dev.to/pineapples/transparent-background-with-css-and-gimp-44eh</guid>
      <description>&lt;p&gt;I wanted to add a transparent background image to each page of an app to create a visual through-line. I found &lt;a href="https://pixabay.com/vectors/cleaning-house-micheline-1294867/" rel="noopener noreferrer"&gt;this&lt;/a&gt; open source image on &lt;a href="https://pixabay.com/" rel="noopener noreferrer"&gt;Pixabay&lt;/a&gt;&lt;br&gt;
that perfectly captured the desired energy for the app:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdaqhimoz3gxabrhb1ouk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdaqhimoz3gxabrhb1ouk.png" alt="original image" width="800" height="424"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I decided to add it to the bottom of each page as a minimized, repeating image. However, the original image at full opacity drew the user's eye and distracted from page content. Reducing the opacity and increasing transparency would improve the user experience.&lt;/p&gt;
&lt;h3&gt;
  
  
  Adding Background Image to App
&lt;/h3&gt;

&lt;p&gt;First, I added the image as a &lt;code&gt;background-image&lt;/code&gt; to the root html tag: &lt;code&gt;body&lt;/code&gt;. My CSS file now looked like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;body&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;background&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./images/cleaning-1294867_1280.png&lt;/span&gt;&lt;span class="dl"&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;h3&gt;
  
  
  Opacity via CSS
&lt;/h3&gt;

&lt;p&gt;Next, I attempted to add opacity with the CSS &lt;code&gt;opacity&lt;/code&gt; tag:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;body&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;background&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./images/cleaning-1294867_1280.png&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.3&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;Unfortunately, the CSS &lt;code&gt;opacity&lt;/code&gt; tag applies to ALL of its child elements as well. The background image is applied to &lt;code&gt;body&lt;/code&gt;, the parent of the entire app, which means simply adding opacity onto &lt;code&gt;body&lt;/code&gt; forced each element in the app to render with matching opacity. This was very hard to read:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3ma6fa1420we4u8qpbfd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3ma6fa1420we4u8qpbfd.png" alt="muted image" width="800" height="371"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are a number of workarounds to this issue, notably using pseudo elements. As I wanted a statically transparent image, I decided to edit the image itself to my desired transparency and load the edited image into the app.&lt;/p&gt;

&lt;h3&gt;
  
  
  GIMP to the Rescue!
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://www.gimp.org/" rel="noopener noreferrer"&gt;GIMP&lt;/a&gt; is a free and open source photo editing service that you can download to your desktop. &lt;/p&gt;

&lt;p&gt;Open your image up in GIMP. To edit transparency and opacity for a full image follow the steps below. (To select only part of the image you can try &lt;a href="https://thomas-cokelaer.info/blog/2016/09/gimp-how-to-make-a-transparent-background/" rel="noopener noreferrer"&gt;this tutorial&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1:&lt;/strong&gt; click Layer → Transparency → Color to Alpha&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdvnyuubmvmra31s9pv6t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdvnyuubmvmra31s9pv6t.png" alt="Step 1" width="800" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2:&lt;/strong&gt; This will open up a window where you can edit the transparency and opacity of the image&lt;/p&gt;

&lt;p&gt;I changed the transparency to 0.300 and maintained opacity at 1.000, but you can play around with these to find the best combination. Make sure to have "preview" clicked so you can see your changes before applying them. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbjfu8wcp87imqwmxd46l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbjfu8wcp87imqwmxd46l.png" alt="Step 2" width="800" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When you're happy with your image click "ok" to apply changes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3:&lt;/strong&gt; Finally, export your image in the appropriate file type. I chose &lt;code&gt;.png&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;(Simply clicking "save" in GIMP will save the image as an &lt;code&gt;.xcf&lt;/code&gt; file.)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4xfsamrwtgfexygugjjd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4xfsamrwtgfexygugjjd.png" alt="Step 3" width="800" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Final Details: Location, Size, Repeat
&lt;/h3&gt;

&lt;p&gt;Now import your newly edited image into your project and update the &lt;code&gt;background-image&lt;/code&gt; url. (Be sure to remove the &lt;code&gt;opacity&lt;/code&gt; tag if you added it.)&lt;/p&gt;

&lt;p&gt;You can add any additional background styling you like. In my case I implemented:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; &lt;code&gt;background-size: 20% auto;&lt;/code&gt; - this sets the background image width at 20% of the viewport and height to auto in proportion to the width&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;background-repeat: repeat-x;&lt;/code&gt; - repeats background horizontally&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;background-position: bottom 5px center;&lt;/code&gt; - positions the background with an offset of 5px from the bottom of the screen&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;background-attachment: fixed;&lt;/code&gt; - fixes background at it's designated position in the viewport, regardless of scroll
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;body {
    background-image: url("./images/tree-home-transparent.png");
    background-repeat: repeat-x;
    background-position: bottom 5px center;
    background-size: 20% auto;
    background-attachment: fixed;
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The Final Product:
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk5pk3sutvdqlmmlh42y3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk5pk3sutvdqlmmlh42y3.png" alt="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k5pk3sutvdqlmmlh42y3.png" width="800" height="372"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>css</category>
      <category>background</category>
      <category>newbie</category>
      <category>gimp</category>
    </item>
    <item>
      <title>Creating a monthly updating calendar in Rails with Whenever gem and a Cron job</title>
      <dc:creator>pineapples</dc:creator>
      <pubDate>Mon, 02 Aug 2021 17:36:41 +0000</pubDate>
      <link>https://dev.to/pineapples/creating-a-monthly-updating-calendar-in-rails-with-whenever-gem-and-a-cron-job-5e6h</link>
      <guid>https://dev.to/pineapples/creating-a-monthly-updating-calendar-in-rails-with-whenever-gem-and-a-cron-job-5e6h</guid>
      <description>&lt;p&gt;For my final portfolio project with the Flatiron School, I updated an app I'd previously created with Sinatra into React and also added additional functionality. This app allows a user to track plant care in their home, particularly watering needs for their plants. The user saw a calendar (created with React Calendar) that rendered a watering schedule on the front end. Calendar data was maintained on the back end with a &lt;code&gt;PlantEvent&lt;/code&gt; model and database. To limit the amount of  data that the database would be responsible for at any given time, the &lt;code&gt;plant_events&lt;/code&gt; table would be updated on the first of the month with the current month's schedule. Thus I needed to implement a recurring method to delete the past month's data and instantiate new database rows for the current month. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fflzby1b3m73kztkuq33r.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fflzby1b3m73kztkuq33r.gif" alt="Calendar Component" width="480" height="308"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I followed &lt;a href="https://dev.to/risafj/cron-jobs-in-rails-a-simple-guide-to-actually-using-the-whenever-gem-now-with-tasks-2omi"&gt;this detailed tutorial&lt;/a&gt; for implementing my recurring job. The steps below show how I set a Cron job to run a Rake task once a month with the &lt;code&gt;whenever&lt;/code&gt; gem.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Step 1. Add &lt;code&gt;whenever&lt;/code&gt; gem and set up the &lt;code&gt;config/schedule.rb&lt;/code&gt; file&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Add the &lt;a href="https://github.com/javan/whenever" rel="noopener noreferrer"&gt;whenever&lt;/a&gt; gem to your Gemfile with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gem 'whenever', require: false
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then run &lt;code&gt;bundle&lt;/code&gt; in the terminal.&lt;/p&gt;

&lt;p&gt;After bundling, run &lt;code&gt;bundle exec wheneverize .&lt;/code&gt; from the root of your Rails application. This creates a file called &lt;code&gt;config/schedule.rb&lt;/code&gt; where you can write the schedule.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Step 2. Create the &lt;code&gt;whenever&lt;/code&gt; schedule for your cron task in &lt;code&gt;config/schedule.rb&lt;/code&gt;&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;whenever&lt;/code&gt; gem has several built-in shorthand calls for commonly used times. To run a task on the first of the month at midnight, you can simply use the built-in &lt;a href="https://stackoverflow.com/questions/30287818/in-whenever-gem-if-we-use-every-month-does-it-mean-the-end-of-month-or-beginn" rel="noopener noreferrer"&gt;&lt;code&gt;1.month&lt;/code&gt; shortcut&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# config/schedule.rb
every 1.month do
  rake 'calendar:update_calendar'
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will call a Rake task called &lt;code&gt;update_calendar&lt;/code&gt; that is namespaced under &lt;code&gt;calendar&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Step 3. Create a Rake task that will perform the needed task when called&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;You can use a Rails generator to generate the Rake task file with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rails g task calendar update_calendar
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates a file called &lt;code&gt;lib/tasks/calendar.rake&lt;/code&gt; with the following boilerplate code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# lib/tasks/calendar.rake
namespace :calendar do
  desc "TODO"
  task update_calendar: :environment do
  end

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

&lt;/div&gt;



&lt;p&gt;Edit the &lt;code&gt;desc&lt;/code&gt; line to describe what your task does and add the code to perform the task inside the block. Be sure to keep the &lt;code&gt;environment&lt;/code&gt; line as that is what &lt;a href="https://stackoverflow.com/questions/876396/do-rails-rake-tasks-provide-access-to-activerecord-models" rel="noopener noreferrer"&gt;loads your environment (including ActiveRecord models)&lt;/a&gt; inside your task. The file now looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;namespace :calendar do
  desc "delete previous month's calendar events and populate current month"
  task update_calendar: :environment do
    PlantEvent.delete_all
    Plant.find_each do |plant|
      if plant.watering_repeat_rate_days
        plant.build_plant_events_collection(plant.watering_repeat_rate_days)
      end
    end
  end

end

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

&lt;/div&gt;



&lt;p&gt;In this case, all existing &lt;code&gt;plant_events&lt;/code&gt; are deleted. Then each &lt;code&gt;plant&lt;/code&gt; instantiates a collection of &lt;code&gt;plant_events&lt;/code&gt; for the current month.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;For reference, the &lt;code&gt;Plant&lt;/code&gt; model looks like:&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# app/models/plant.rb
require 'date'
require 'active_support'

class Plant &amp;lt; ApplicationRecord
  belongs_to :user
  has_many :plant_events, dependent: :destroy

  def build_plant_events_collection(watering_repeat_rate_days, start_date = Date.today)
    event_date = start_date

    if watering_repeat_rate_days
      while event_date &amp;lt; start_date.at_beginning_of_month.next_month
        self.plant_events.create(date: event_date, event_type: "water")
        event_date = event_date.advance(days: watering_repeat_rate_days)
      end
    end

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Step 4. Write the crontab file for your jobs&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Finally, write the crontab file that will check for cron jobs and run them in the background. You can read more about cron &lt;a href="https://help.ubuntu.com/community/CronHowto" rel="noopener noreferrer"&gt;here&lt;/a&gt; and &lt;a href="https://en.wikipedia.org/wiki/Cron" rel="noopener noreferrer"&gt;here&lt;/a&gt;. Basically cron lets you run background jobs at specified intervals, and the crontab tracks these jobs by name. &lt;/p&gt;

&lt;p&gt;For production environments (the default) run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bundle exec whenever --update-crontab 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When working in development, add the development flag &lt;code&gt;--set environment='development'&lt;/code&gt; and run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bundle exec whenever --update-crontab --set environment='development'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the cron job is all set to run the rake task once a month to update the calendar.&lt;/p&gt;

</description>
      <category>rails</category>
      <category>cron</category>
      <category>whenever</category>
      <category>calendar</category>
    </item>
    <item>
      <title>Handling a Nested Form with a Rails Back End and JavaScript Front End</title>
      <dc:creator>pineapples</dc:creator>
      <pubDate>Wed, 30 Jun 2021 23:48:40 +0000</pubDate>
      <link>https://dev.to/pineapples/handling-a-nested-form-with-a-rails-back-end-and-javascript-front-end-47o9</link>
      <guid>https://dev.to/pineapples/handling-a-nested-form-with-a-rails-back-end-and-javascript-front-end-47o9</guid>
      <description>&lt;p&gt;For my fourth project with the Flatiron program I created a single page application that used a Rails API for the backend server with a JavaScript, HTML, and CSS frontend to handle page rendering and styling. The basic premise of the app was that a user could create journal entries using a timer and add a keyword to their entry. One aspect of building this app that proved to be a great learning experience was implementing a nested form. I wanted the seamless user experience of creating a new journal entry and adding a keyword with one click. I had previously implemented a nested form in a pure Rails app. Doing so from a JavaScript fetch call, however, added a new challenge.&lt;/p&gt;

&lt;p&gt;I coded my project with a many-to-many relationship between entries and keywords, using a join table for the two models called entry_keywords. For clarity, those associations looked 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 Entry &amp;lt; ApplicationRecord
  has_many :entry_keywords, dependent: :destroy
  has_many :keywords, through: :entry_keywords
end

class Keyword &amp;lt; ApplicationRecord
  has_many :entry_keywords, dependent: :destroy
  has_many :entries, through: :entry_keywords
end

class EntryKeyword &amp;lt; ApplicationRecord
  belongs_to :entry
  belongs_to :keyword
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  MVP Goals
&lt;/h2&gt;

&lt;p&gt;For the minimum viable product (MVP), I decided to allow a user to assign one keyword to a new entry, rather than many at once. This could be an existing keyword or a new keyword. If the user selected an existing keyword, it would be found in the database and an association between it and the new entry would be created. If the user created a new keyword, that keyword would be instantiated as a keyword, persisted, AND assigned an association with the new journal entry.  As the bulk of the application is concerned with creating, filtering, and reading journal entries, I decided that the entry model should be the main model for my form. This also meant that form processing would be handled by the entries_controller on the backend.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rails Back End Set-Up
&lt;/h2&gt;

&lt;p&gt;First I added the accepts_nested_attributes_for macro to the entry model. My &lt;code&gt;entry.rb&lt;/code&gt; file now looked 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 Entry &amp;lt; ApplicationRecord
  has_many :entry_keywords, dependent: :destroy
  has_many :keywords, through: :entry_keywords
  accepts_nested_attributes_for :keywords
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This macro is a class method provided by ActiveRecord that will create a new method on your main model, &lt;code&gt;&amp;lt;othermodelname&amp;gt;_attributes=&lt;/code&gt;. This will allow you to create an object of one type through the class of the main object.&lt;/p&gt;

&lt;p&gt;For clarity, we can add the model names back in and see what’s actually happening.&lt;/p&gt;

&lt;p&gt;The entry_controller create action, will receive the params that are send back from the front end. As the front end uses JavaScript, rather than a Rails nested form, we’ll have to make sure to code the params to include what’s needed. A correct version of params, with the keyword_attributes tag looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pry&amp;gt;params
=&amp;gt;#"entry"=&amp;gt;{"body"=&amp;gt;"sample entry", "time_interval"=&amp;gt;1.0, "keywords_attributes"=&amp;gt;{"name"=&amp;gt;"nature"}}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To get params to look like this, the correct information needs to be passed into the fetch call.&lt;/p&gt;

&lt;h2&gt;
  
  
  Passing Params from Front End
&lt;/h2&gt;

&lt;p&gt;Let’s say the values we want to pass back are encapsulated in the variables listed below. To ensure that they end up in our params hash just the way our backend is expecting, assign those values to an JavaScript object (named data) that imitates the expected params hash. Then pass that data object as a JSONified string into the body key of the configuration object. Finally, pass that configObj as the second argument into the fetch call. This particular configuration object informs the fetch call that is sending a POST request, and also passes the necessary data about entry and keyword to the backend params:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//info to pass to params
const body = "sample entry";
const timeInterval = 0.16666666666666666;
const keywordAttributes = {name: "nature"}

// imitate params hash with JavaScript object
const data = {
body: "sample entry",
time_interval: 1.0,
keywords_attributes: {name: "nature"}
};

//create configuration object
    const configObj = {
    method: "POST",
    headers: {
        "Content-Type": "application/json"
    }
    body: JSON.stringify(data),
}

fetch("url_to_backend_controller_action", configObj)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Back End Form Handling
&lt;/h2&gt;

&lt;p&gt;The above fetch call will reach an endpoint on the backend. In this example, the backend endpoint will be the create action in the entries_controller.&lt;/p&gt;

&lt;p&gt;Remember params?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pry&amp;gt;params
=&amp;gt;#"entry"=&amp;gt;{"body"=&amp;gt;"sample entry", "time_interval"=&amp;gt;0.16666666666666666, "keywords_attributes"=&amp;gt;{"name"=&amp;gt;"nature"}}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When the Entry controller encounters the &lt;code&gt;keywords_attributes&lt;/code&gt; line in the params hash, it will be spurred to call a method with a matching name. In this case, add that matching method (&lt;code&gt;keywords_attributes=&lt;/code&gt;) to the Entry model:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def keywords_attributes=(keyword_params)
    name = keyword_params[:name].downcase.strip
    if !name.empty?
        keyword = Keyword.find_or_create_by(name: name)
        self.keywords &amp;lt;&amp;lt; keyword unless self.keywords.include?(keyword)
    end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(Side note: As this is a many-to-many relationship, the form could ALSO have been coded to accept multiple keyword instances. In that case, params would have needed to include another field for the ids of existing keywords as well as the keywords_attributes field. However, for simplicity, the form currently only allows adding one keyword to an entry. This means the back end can simply use the name attribute, whether finding or creating a keyword.)&lt;/p&gt;

&lt;p&gt;Here &lt;code&gt;keywords_attributes=&lt;/code&gt; is called with an argument of the &lt;code&gt;keywords_attributes&lt;/code&gt; from the params hash. As &lt;code&gt;keywords_attributes&lt;/code&gt; is a key in the params pointing to the value of &lt;code&gt;{"name"=&amp;gt;"nature"}&lt;/code&gt; , it may be simpler to say that the Entry model method &lt;code&gt;keywords_attributes=&lt;/code&gt; is called with an argument of that value: &lt;code&gt;{"name"=&amp;gt;"nature"}&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;So on encountering &lt;code&gt;keywords_attributes&lt;/code&gt; in params, this method call is made: &lt;code&gt;keywords_attributes=({"name"=&amp;gt;"nature"})&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;And the method does four things:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1)&lt;/strong&gt; First it grabs the specific information that we are looking for, (the value at the key of name) and also sanitizes that input with &lt;code&gt;.downcase&lt;/code&gt; and &lt;code&gt;.strip&lt;/code&gt;. (We want to always compare apples to apples, so we will always save keyword names as all lowercase. Anytime we check for them in the database, we’ll do so with a lowercase. In addition, we don’t want to save random white space or empty strings to our database so be sure to &lt;code&gt;.strip&lt;/code&gt; that away.)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2)&lt;/strong&gt; Next, check whether the string is empty to verify whether to do steps 3 and 4.&lt;/p&gt;

&lt;p&gt;(Side note: in Ruby an empty string &lt;code&gt;""&lt;/code&gt; evaluates to false while a string of just space characters &lt;code&gt;" "&lt;/code&gt; evaluates to true .)&lt;/p&gt;

&lt;p&gt;So if the string is empty, it evaluates to false and nothing else happens in this method. In that case, no keyword is assigned to the new entry that is being created. But if the string has some value, continue on to the next step.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3)&lt;/strong&gt; Here call the ActiveRecord macro &lt;code&gt;find_or_create_by&lt;/code&gt; and pass in for both the database column name to look in (name) and the value to check for (the local variable &lt;code&gt;name&lt;/code&gt; from step 1). &lt;code&gt;find_or_create_by&lt;/code&gt; finds and then returns the first instance that matches the query. If it does not find one, it will instead instantiate a new instance with the information that was passed in and return that new instance. The return value of this method, a new or previously existing instance of the Keyword model, is assigned to a local variable, &lt;code&gt;keyword&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4&lt;/strong&gt;) Finally, while still inside the &lt;code&gt;if&lt;/code&gt; block, add the keyword instance that was returned in step 3 to the collection of keywords on this particular journal entry.&lt;/p&gt;

&lt;p&gt;Then the &lt;code&gt;keywords_attributes=&lt;/code&gt; method ends and you are back in the &lt;code&gt;entries_controller&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Once the entry is instantiated, render it to the frontend using json, and include the keyword. This looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def create
    entry = Entry.new(entry_params)

    if entry.save
      render json: entry, include: [:keywords]
    else
      render json: entry.errors.full_messages, status: :unprocessable_entity
    end
  end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Return to Front End
&lt;/h2&gt;

&lt;p&gt;Finally, returning to the front end, check the console logged response after parsing it’s JSON:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fetch("backend/url", configPostObject)
    .then(response =&amp;gt; response.json())
    .then(json =&amp;gt; console.log(json))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open up the browser tools and you can see that something like this has been console logged:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// entry instance:
{id: 145, body: "sample entry", time_interval: 1, created_at: "2021-05-16T01:22:44.802Z", updated_at: "2021-05-16T01:22:44.802Z", …}
body: "sample entry"
created_at: "2021-05-16T01:22:44.802Z"
id: 145

// keyword array

keywords: Array(1)
0: {id: 4, name: "nature", created_at: "2021-05-12T17:22:45.771Z", updated_at: "2021-05-12T17:22:45.771Z"}
length: 1
__proto__: Array(0)
time_interval: 1
updated_at: "2021-05-16T01:22:44.802Z"
__proto__: Object
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As the console logged object shows, the entry and keyword association were successfully persisted and returned to the front end. This means the nested form was effective for both entry and keyword information. The app successfully coordinated between a Rails backend and JavaScript frontend to handle a nested form with one click!&lt;/p&gt;

&lt;p&gt;** Originally published May 16, 2021 via github.io&lt;/p&gt;

</description>
    </item>
    <item>
      <title>10 Basic Coding Terms For Beginners</title>
      <dc:creator>pineapples</dc:creator>
      <pubDate>Mon, 21 Jun 2021 23:29:15 +0000</pubDate>
      <link>https://dev.to/pineapples/10-basic-coding-terms-for-beginners-24b3</link>
      <guid>https://dev.to/pineapples/10-basic-coding-terms-for-beginners-24b3</guid>
      <description>&lt;p&gt;A really super beginner list of vocab words for code, because sometimes as I’m learning, I just want a brief 10 second synopsis on a term. (When language matters, this list is specific to Ruby.) So here goes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Variable: a placeholder for a value. This is represented by a “bare word” data type. It allows you to access a value (which could be an extremely long bit of information) via your (typically short) variable name. In addition, as the name implies, a variable’s value can vary, though the specific rules on how it can vary, depend on the language. You can think of a variable as a labeled drawer holding some value.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Constant: this is like a variable, in that it is also a placeholder for a value. However, unlike a variable which can vary, a constant will be set equal to a value once in the course of your program and then it should not be reassigned. (You technically could reassign the constant. The language won’t physically stop you, but you shouldn’t reassign it!) Anytime you call the constant’s name, it will (or should!) always point to the value to which it was originally assigned. In Ruby, a constant starts with a capital letter.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Method: a set of instructions for something you want your code to do. Methods must be “defined” before they can be “called” or “invoked” at one (or many!) points later.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#this is the method definition:
def do_something
  puts "Hello"
end

#this is the method invocation:
do_something
=&amp;gt; Hello
nil
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Parameters: a method can be defined to take information. The parameters are the placeholders in the method definition for that information. For example, we could make our above method take an argument containing some bit of data, and &lt;code&gt;puts&lt;/code&gt; out the value of that data, rather than always &lt;code&gt;put&lt;/code&gt;ting “Hello”:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def do_something(data)
  puts data
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Arguments: these are very similar to parameters. These are the actual bits of data that are passed into a method’s parameter spot(s) when the method is called. An argument can be raw data (like a “string”) or it can be the name of a variable, where the variable name points to the raw data:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#passing raw data in as an argument:
do_something("hi")
//=&amp;gt; "hi"
nil

#assigning a value to a variable and then passing that variable in as the argument:
greeting = "hola"

do_something(greeting)
//=&amp;gt; "hola"
nil 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Return Value: In Ruby, a method implicitly (meaning without you having to say so) returns the value of the last line of code - unless you specifically return at some other point. In all of our examples above, &lt;code&gt;nil&lt;/code&gt; is the return value of calling the &lt;code&gt;do_something&lt;/code&gt; method. (Our &lt;code&gt;do_something&lt;/code&gt; method is itself invoking the &lt;code&gt;puts&lt;/code&gt; method on its last line. The return value of &lt;code&gt;puts&lt;/code&gt; is &lt;code&gt;nil&lt;/code&gt;, so our method &lt;code&gt;do_something&lt;/code&gt; returns &lt;code&gt;nil&lt;/code&gt; or the value of the last evaluated line of code. If we wanted &lt;code&gt;do_something&lt;/code&gt; to simply return &lt;code&gt;hello&lt;/code&gt;, we could type hello on the last line inside the function (we would still need to use &lt;code&gt;puts&lt;/code&gt; if we also wanted the method to output hello):
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def do_something
  puts "hello"
  "hello"
end

do_something
//=&amp;gt; hello #this is the output 'hello'
hello #this is the return from the last line inside the method
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Terminal: the terminal is where code is “run” and evaluated. This allows you to run a program to “test” it with special tests (written to compare expected code results with actual code results) or see the output, especially in the case of a ‘command line program.’&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Text Editor This is the place where you create and edit code projects, similar to using Microsoft Word or Google Docs to write a paper. Text editors are loaded up with code languages; they allow you to format code documents based on the language you are writing, as well as package up multiple files into a larger project. Some examples of text editors include Atom and VS Code. You can choose to run a terminal (where you actually run the code) from within a text editor or separately. Regardless of whether you run your terminal separately or inside your text editor, you generally operate the text editor and the terminal hand in hand while you are designing code. You’ll type in the text editor to write or edit code then run that code in the terminal to see what happens.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Keywords: These are reserved words in a code language that have already been assigned meaning by the writers of the language. Because they are reserved (and already have definitions), they should not be used to name variables or methods. Doing so would cause confusion as you would be over-writing existing definitions with special, temporary definitions. Some examples of Ruby keywords are: &lt;code&gt;if&lt;/code&gt;, &lt;code&gt;else&lt;/code&gt;, &lt;code&gt;def&lt;/code&gt;, &lt;code&gt;yield&lt;/code&gt;, &lt;code&gt;do&lt;/code&gt;, &lt;code&gt;puts&lt;/code&gt;, &lt;code&gt;print&lt;/code&gt;, etc.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Program: this is a collection of code that can be compiled and run together. A program can be as simple as one file, or as complicated as you’d like. Ultimately this is a blanket term for a collection of code that performs some (or many) action(s).&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;And there you have it! These are some quick definitions to a few of the vocabulary words that I regularly found myself Googling at the beginning of my coding journey. This is by no means comprehensive, even for the vocabulary words above. As with everything in code, you could go much (much) deeper into these words, their meaning, and how they interact with so many other aspects of code.&lt;/p&gt;

&lt;p&gt;** Originally published April 30, 2021 via github.io&lt;/p&gt;

</description>
      <category>keywords</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
