Stardog JavaScript Exercise 2

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 2</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 FUNCTION SO THAT TESTS PASS.
// See the instructions and test results to the right.
function 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;
}

function mapArray(array, callback) {
	const output = [];
	
  array.forEach(value => {
  	output.push(callback(value));
  });
  
  return output;
}

const map = (input, callback, context) => {
  if (context) callback = callback.bind(context);
	
	const isObject = typeof input === 'object';
  
  const output = isObject
  	? mapObject(input, callback)
    : mapArray(input, callback);
	
  return output;
};

/**
 * BEGIN CODE REQUIRED FOR TESTS. DO NOT REMOVE.
 */
const markdownConverter = new showdown.Converter();
const promptMarkdown = `
## Fixing the Context

The "basic" version of \`map\` that you wrote in the last exercise works well
enough, but it would be nicer if it were able to accept a \`context\` argument
that would allow callers to specify the context (or \`this\`) object for the
callback function. For example, the following call to the basic \`map\` function
could produce some weird or unexpected behavior:

\`\`\`javascript
class Mapper {
    constructor(value) {
        this.value = value;
    }

    multiply(input) {
        return input * this.value;
    }
}

const mapper = new Mapper(2);
const mappedValues = map([1, 2, 3, 4], mapper.multiply);
\`\`\`

Let's assume the person who wrote the above code expects \`mappedValues\` to be
\`[2, 4, 6, 8]\`. One way we could make this work is to allow the caller to pass
a \`context\` (or \`this\`) argument to the \`map\` function as a third argument,
as in: \`map([1, 2, 3, 4], mapper.multiply, mapper)\`.

# EXERCISE

Make your map function accept a third argument, \`context\`, that specifies the
\`this\` object that is the context in which the callback is...