The problems below all require that you write a function that performs a simple data transformation on a generic, opaque set of data.
Note that many functions are variadic by way of the rest operator. If you're not sure what this means, read this.
These are the rules:
- Other than the function itself, you may not declare variables (no
var,let, orconst) - You may not use branch statements (no
if,else,switch, etc) - You may not use loops (no
for,do,while) - You may not mutate state, including state internal to the function
For each problem, I'll provide:
- The name of the function
- The function's parameters and their types
- The function's return type based on what the function needs to do
Finish the function:
const sum = (...nums) =>
Parameter nums: An array of numbers
Returns: The sum of nums (as a number)
Example Usage:
joinStrings(1, 2, 3) //=> 6
Finish the function:
const joinStrings = (...strings) =>
Parameter strings: An array of strings
Returns: The concatenation of strings (as a string)
Example Usage:
joinStrings('a', 'bc', 'd') //=> 'abcd'
Finish the function:
const joinArrays = (...lists) =>
Parameter lists: An array of arrays
Returns: The result of merging all of the arrays into a single array
Example Usage:
joinArrays([1], [2, 3], [4]) //=> [1, 2, 3, 4]
Finish the function:
const mergeObjects = (...objs) =>
Parameter objs: An array of objects
Returns: The result merging all of the objects into a single object
Example Usage:
mergeObjects({ a: 1 }, { b: 2, c: 3 }, { d: 4 }) //=> { a: 1, b: 2, c: 3, d: 4 }
Finish the function:
const objFromPairs = (...pairs) =>
Parameter pairs: An array of arrays (pairs). Pairs are always going to be two-element arrays. The first element will be a valid object-key type (string, number, or symbol).
Returns: An object created by merging the pairs. The first element of a pair will become an object key, the second element of a pair will become that key's value.
Example Usage:
objFromPairs(['a', 1], ['b', 2], ['c', 3]) //=> { a: 1, b: 2, c: 3 }
Finish the function:
const pairsFromObj = obj =>
Parameter obj: A regular JS object.
Returns: An array of arrays (pairs). Each key of obj will be converted into a pair, where the first element of the pair is the key itself, and the second element is the key's value.
Example Usage:
pairsFromObj({ a: 1, b: 2, c: 3 }) //=> [['a', 1], ['b', 2], ['c', 3]]
Hint: There's a native JS method that performs this operation.
Finish the function:
const map = (fn, list) =>
Parameter fn: A function that accepts an item from list and returns anything. This is the function that would usually be passed to the native map as list.map(fn).
Parameter list: The list which will be iterated over and whose items will have fn applied.
Returns: An array.
You must recreate the native
Array.prototype.mapusing onlyArray.prototype.reduce.
The follow two expressions will be equivalent:
/* Native method */ list.map(fn);
/* Your Derived method */ map(fn, list);
Example Usage:
/* Native method */ [1, 2, 3].map(x => x + 1) //=> [2, 3, 4]
/* Your Derived method */ map(x => x + 1, [1, 2, 3]) //=> [2, 3, 4]
Finish the function:
const filter = (fn, list) =>
Parameter fn: A predicate function that accepts an item from list and returns a truthy value. The truthiness determines whether or not the item is included in the returned list. This is the function that would usually be passed to the native filter as list.filter(fn).
Parameter list: The list which will be iterated over and whose items will have fn applied.
Returns: An array.
You must recreate the native
Array.prototype.filterusing onlyArray.prototype.reduce.
The follow two expressions will be equivalent:
/* Native method */ list.filter(fn);
/* Your Derived method */ filter(fn, list);
Example Usage:
/* Native method */ [1, 2, 3].filter(x => x > 1) //=> [2, 3]
/* Your Derived method */ filter(x => x > 1, [1, 2, 3]) //=> [2, 3]
Finish the function:
const strsToObj = (...strs) =>
Write a function that receives a list of strings and from that list creates an object where each string from the list becomes a key, and the key value is 0.
Example Usage:
strsToObj('a', 'b', 'c') //=> { a: 0, b: 0, c: 0 }
Finish the function:
const reverseKeys = obj =>
Write a function that receives an object and returns a copy of that object, but with its keys reversed.
Example Usage:
reverseKeys({ abc: 1, def: 2}) //=> { cba: 1, fed: 2 }
Finish the function:
const swapKeyValues = obj =>
Write a function that receives an object and returns a copy of that object, but with it's keys and values swapped.
Example Usage:
swapKeyValues({ a: 'b', c: 'd' }) //=> { b: 'a', d: 'c' }
Finish the function:
const omitKeys = (keys, obj) =>
Write a function that receives a list of strings and an object, and returns a copy of that object, but without any properties whose key matches a string in the received list.
Example Usage:
omitKeys(['a', 'b'], { a: 1, b: 2, c: 3}) //=> { c: 3 }
Finish the function:
const capitalize = str =>
Write a function that receives a string and returns that string but with the first letter capitalized.
Hint: This can be done elegantly using a combination of the rest operator and parameter destructuring.
Example Usage:
capitalize('alexEden') //=> 'AlexEden'
Finish the function:
const mapByProp = (prop, list) =>
Write a function that receives a list of objects and returns an object of those objects where each object has a key value extracted from a specified prop.
Example Usage:
mapByProp('x', [{ x: 'a'}, {x: 'b'}])
/* {
a: { x: 'a'},
b: { x: 'b'},
} */
Finish the function:
const multiFilter = (fns, list) =>
Write a function that receives a list of predicate functions (fns) and a list of items. multiFilter should work just like filter, except that it runs each item through multiple predicates, wherein all predicates must pass.
Example Usage:
multiFilter([x => x > 1, x => x < 4], [1, 2, 3, 4]) //=> [2, 3]