Stardog JavaScript Exercise 3

by Cody Bennett

HTML

<link rel="stylesheet" href="//cdn.jsdelivr.net/jasmine/1.3.1/jasmine.css">
<script src="//cdn.jsdelivr.net/jasmine/1.3.1/jasmine.js"></script>
<script src="//cdn.jsdelivr.net/jasmine/1.3.1/jasmine-html.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/showdown.min.js"></script>
<!-- NOTE: THERE IS NO NEED TO EDIT ANY HTML FOR THIS TASK. -->
<link href="https://fonts.googleapis.com/css?family=Lato:400,700&display=swap" rel="stylesheet">
<h1>Stardog JavaScript Exercise 3</h1>
<div id="exercise_prompt"></div>

CSS

/* NOTE: THERE IS NO NEED TO EDIT CSS FOR THIS TASK. */
body {
  font-family: 'Lato', sans-serif;
  color: #f1f1f1;
  background-color: rgb(32, 38, 46);
  line-height: 1.5;
  padding: 20px;
}

code {
  background-color: rgb(29, 33, 40);
  color: rgb(216, 89, 38);
  display: inline-block;
}

#HTMLReporter {
  background-color: #fff;
}

JavaScript

// YOUR TASK IS TO REWRITE THIS CLASS SO THAT TESTS PASS.
// See the instructions and test results to the right.
class MappableObject {
  constructor(val) {
  	this.val = val;
  }
  
  mapObject(object, callback) {
    const keys = Object.keys(object);
    const values = Object.values(object);

    const output = {};

    keys.forEach((key, index) => {
      output[key] = callback(values[index]);
    });

    return output;
  }
  
  mapArray(array, callback) {
    const output = [];

    array.forEach(value => {
      output.push(callback(value));
    });

    return output;
  }
 
	map(callback, context) {
  	if (context) callback = callback.bind(context);
	
    const isObject = typeof this.val === 'object';

    const output = isObject
      ? this.mapObject(this.val, callback)
      : this.mapArray(this.val, callback);

    return output;
  }
}

/**
 * BEGIN CODE REQUIRED FOR TESTS. DO NOT REMOVE.
 */
const markdownConverter = new showdown.Converter();
const promptMarkdown = `
## Create a Mappable Object Class

Okay, your solutions are working great at this point. But now, let's say that,
for convenience's sake, we'd like to always use the \`.map\` syntax for mapping
instead of calling a separate \`map\` function. We don't want to modify
\`Object.prototype\` to put a \`map\` method there, of course, so what we're going
to do instead is create a \`MappableObject\` class that can be used like so once
it is created:

\`\`\`javascript
const mappable = new MappableObject({
    a: 1,
    b: 2,
    c: 3,
    d: 4
});
const mapped = mappable.map((val) => val * 2);
// mapped => { a: 2, b: 4, c: 6, d: 8 }
\`\`\`

NOTE: The \`.map\` method should also be capable of taking a second \`context\`
argument, just like the \`Array.prototype.map\` method.

## Exercise

Create a MappableObject class whose instances are mappable as in the above example.

### HINTS

All that you need to write is the class itself.

Again, no error checking is necessary. Just assume that all arguments...