Pen Settings

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URL's added here will be added as <link>s in order, and before the CSS in the editor. If you link to another Pen, it will include the CSS from that Pen. If the preprocessor matches, it will attempt to combine them before processing.

+ add another resource

You're using npm packages, so we've auto-selected Babel for you here, which we require to process imports and make it all work. If you need to use a different JavaScript preprocessor, remove the packages in the npm tab.

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

+ add another resource

Use npm Packages

We can make npm packages available for you to use in your JavaScript. We use webpack to prepare them and make them available to import. We'll also process your JavaScript with Babel.

⚠️ This feature can only be used by logged in users.

Code Indentation

     

Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

HTML Settings

Here you can Sed posuere consectetur est at lobortis. Donec ullamcorper nulla non metus auctor fringilla. Maecenas sed diam eget risus varius blandit sit amet non magna. Donec id elit non mi porta gravida at eget metus. Praesent commodo cursus magna, vel scelerisque nisl consectetur et.

            
              main#app.p3.max-width2.mx-auto
  header.mb3.border-bottom.border-silver
    h2.h2 Heyo 👋
    h1.h1.lh-lg An introduction to <code class="code">.map, .filter, .reduce</code> by making a fresh fruit salad (🥗).
  
  section
    article.mb3
      p.h3 Any good fruit salad should be brimming with nice stuff; carefully selected, chopped and mixed into a tasty bowl of goodness.
      p.h3 They're also great for explaining JavaScript's more functional methods, which undoubtedly will be a good addition to your developer skills.
      p.h3 Hungry yet? Good. Let's get chopping with some basic examples.
    
    concept-explainer(
      title="Chop the fruit into pieces"
      subtitle="Transforming with .map")
      
      code-example(
        slot="right-of-title"
        title="Example") array.map(x => x.value)
      
      template(slot="body")
        p.mt0 Since there's not much fun with a fruit salad if we just throw in our fruits as they are into a bowl and call it a day (that's just a bowl of fruit, eck...), we'll chop them into pieces first. <code class="code">.map</code> works wonders for this. Let's try it out.
      
        code-example(title="Code Example").
          const fruits = ['🍎', '🍌', '🍈', '🍉', '🌶️', '🍊']

          const chop = (fruits, pieces = 4) =>
            fruits.map(type => 
              ({ type, pieces })

              /* ☝️ ES6 allows us to avoid typing unnecessary 
                 key, value pairs if there are arguments 
                 with the same name within the same scope.
                 
                 Also ({ type, pieces }) is simply shorthand
                 for "return { type, pieces }".
              */
            )

          const choppedFruits = chop(fruits)

        p What! Our fruits got sliced and diced into 4 pieces each and returned to us in a neat container arranged by type. I wish my kitchen could do that in real life.
        
        p So, what's happening? By running the <code>.map</code> method on our <code>fruits Array</code>, we end up with this neat Array of Objects:
        
        code-example(title="After using .map on the fruits array, we get...").
        
          console.log(choppedFruits)
          /*
          [
            { type: '🍎', pieces: 4 },
            { type: '🍌', pieces: 4 }
            ... etc.
          ]
          */
        
        p Behind the scenes, <code>.map</code> will loop through your array, apply the transformations that you defined, and finally return a new array with the transformed data back to you. What's key here is that the new array it's own copy, and not that the original array was altered (or "mutated").
        
        p Since it's a completely new array, we don't have to worry about our original array being permanently changed. It's not, which allows us to keep transforming the original into many different directions, if you need to.
        
        p This "immutability" is a common trait for both <code>.map, .filter, and .reduce</code>, and it's generally a good thing to keep in mind when you want to avoid unwanted side effects when working with arrays.
      
    concept-explainer(
      title="What's that 🌶️ doing in there?"
      subtitle="Filtering out stuff with .filter"
      class="mt3")
        
        code-example(
          slot="right-of-title"
          title="Example") array.filter(x => x !== y)
        
        template(slot="body")
          p.mt0 Oh no! We've accidentally chopped a super spicy chili pepper into our lovely fruit salad. That won't do -  unless you like a fiery kick with your fruit.
          
          p If this was in a real kitchen, we'd have to tediously pick out all the pepper pieces, wasting our time. Luckily, we don't have this problem in JavaScript as we can just use <code>.filter</code> to pick out that chili in a zinch. Let's give it a shot.
          
          code-example(
            title="Applying .filter to our array of chopped fruits").
              const removeChilis = fruits =>
                fruits.filter(fruit => fruit.type !== '🌶️')
              
              const fruitsWithoutChilis = removeChilis(choppedFruits)
              
              console.log(fruitsWithoutChilis)
              
              /* Chili's out. All good.
                [
                  { "type": "🍎", "pieces": 4 },
                  { "type": "🍌", "pieces": 4 },
                  { "type": "🍈", "pieces": 4 },
                  { "type": "🍉", "pieces": 4 },
                  { "type": "🍊", "pieces": 4 },
                  { "type": "🍓", "pieces": 4 }
                ]
              */
            
          p Ah, much better. The <code>.filter</code> method makes it easy for us to include or exclude items in an array (or arrays of Objects) and continue using the newly returned, and filtered, array for new stuff.
          
          p Keep in mind, that filtering doesn't always mean filtering things out as in a <code>x !== y</code> fashion. It can just as well be the other way around as in "give me only that 🌶️ and leave out the rest", by saying <code>fruit.type === '🌶️'</code>.

    concept-explainer(
      title="Mixing it together, 🥗-time"
      subtitle="Reducing multiple things to one thing with .reduce"
      class="mt3")
        
        code-example(
          slot="right-of-title"
          title="Example") array.reduce((a, b) => a + b, c)
        
        template(slot="body")
          p.mt0 Finally, without any fiery surprises, we can mix our tasty fruit pieces together into a grand fruit salad. The <code>.reduce</code> method is great for this, since it allows us to loop through all of our chopped fruits and add them into the bowl one by one until we end up with one, finished and mixed bowl.
          
          p Let's have a look at that.
          
          code-example(
            title="Applying .reduce to our array of chopped fruits").
              const mix = (fruits, bowl = '') =>
                fruits.reduce(
                  (content, fruit) => content + fruit.type
                , bowl)
              
              /*
                This yields a String `🍎🍌🍈🍉🍊🍓` because
                we're just concatinating these guys together.
              */
              const fruitSalad = mix(fruitsWithoutChilis)
              
              // But is it really a fruit salad? Let's check...
              console.log(fruitSalad === `🍎🍌🍈🍉🍊🍓` ? '🥗' : '😱')

              // 🥗, yay!
            
          p We did it! With a little help from <code>.reduce</code> we could mix all our fruit pieces into one bowl. So, what happened here?
          
          p <code>.reduce</code> is a very interesting method that can do tons of complex stuff, which is out of scope for this piece, but the gist of is that you <em>"take multiple values and calculate them into one final value"</em>.
          
          p A typical use case is summing up stuff, like counting how many fruit pieces there were in total. The uses are endless when you start to really get a grasp of it.
          
          p One gotcha is the initial value that you can pass a <code>.reduce</code> method. In our case we pass an empty <code>bowl String</code>, but it can basically be anything. A number, an Array, an Object, etc.
          
          p The initial value can be a bit strange at first, but in our fruit salad example you can try and think of it as the empty bowl itself. It is "connected" to the <code>content</code> variable, so whenever we do an operation, we're looking into the bowl and adding more stuff to it's <em>current</em> content.
          
          p Until we don't have anything left, that is. Then <code>.reduce</code> stops and returns the final result.
        
    footer
      p If the examples were interesting to you and you want to learn more about all the cool things that you can do with Arrays, <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array">hop over to MDN</a>. It's a great resource.
      
      p Thanks for reading ✌️.
            
          
!
            
              // Typography
.lh-lg { line-height: 125%; }
.pre { white-space: pre; }

// Background Colors
.bg-slate-black { background-color: #1B2B34; }
.bg-ghostwhite { background-color: ghostwhite; }

// Sizing
.max-width2 { max-width: 800px; }
            
          
!
            
              /*---
| Setup: Preparing stuff for later
|----
*/
// salad: '🥗'
const ingredients = {
  apple: '🍎',
  pear: '🍐',
  tangerine: '🍊',
  lemon: '🍋',
  banana: '🍌',
  watermelon: '🍉',
  grapes: '🍇',
  strawberry: '🍓',
  melon: '🍈',
  pepper: '🌶️'
}

/*---
| Component: Code Example
|----
*/
Vue.component('CodeExample', {
  props: {
    title: {
      type: String,
      default: ''
    }
  },
  template: `
    <div class="c-code-example">
      <div class="h5 bold mb1" v-if="title" v-text="title"></div>
      <code :class="'block p2 bg-slate-black white rounded'">
        <div class="pre"><slot /></div>
      </code>
    </div>
  `
})

/*---
| Component: Concept Explainer
|----
*/
Vue.component('ConceptExplainer', {
  props: {
    title: {
      type: String,
      default: 'Title'
    },
    subtitle: {
      type: String,
      default: 'Subtitle'
    }
  },
  template: `
    <div class="c-concept-explainer">
      <header class="c-concept-explainer__header" :class="'flex items-center justify-between py2 px3 bg-ghostwhite border border-silver rounded-top'">
        <section>
          <div class="h5 mb0 gray" v-text="subtitle"></div>
          <div class="h2 mt0 mb0" v-text="title"></div>
        </section>
        <slot name="right-of-title"/>
      </header>
      <section class="c-concept-explainer__body" :class="'p3 border-left border-bottom border-right border-silver rounded-bottom'">
        <slot name="body" />
      </section>
    </div>
  `
})

new Vue({
  el: '#app'
})
            
          
!
999px
🕑 One or more of the npm packages you are using needs to be built. You're the first person to ever need it! We're building it right now and your preview will start updating again when it's ready.

Console