I used to think that fizzbuzz
was a stupid way to test if someone is a developer.
Now I think that it's a good litmus test.
However, I think I've found a better one...
My expectation is that a mid-senior level developer should be able to:
- write this in 30-60 minutes
- debug / fine tune within another 60 minutes
- publish within another 60 minutes
- take another 60 minutes for leeway
If a developer cannot solve this problem within 2 days - because maybe they need a break to clear their head after overthinking it, or they've never had to work independently before - then I don't think they're a good hire for jobs that require any sort of data or API manipulation.
Given JSON that looks like this:
var data = {
foo: [
{
bar: [
{
baz: ["apples", "bananas"],
},
],
quux: [
{
do: ["red thing", "blue thing"],
},
],
},
],
grault: {
name: "Bob",
age: 37,
grumpy: false,
nullish: null,
},
answer: 42,
};
Can you produce a function that outputs it as YAML?
foo:
- bar:
- baz:
- "apples"
- "bananas"
quux:
- do:
- "red thing"
- "blue thing"
empty: []
grault:
name: "Bob"
age: 37
grumpy: false
nullish: null
silly: {}
answer: 42
The conversion is 1:1. This is just testing that you know how to use basic Object and Array methods, and keep track of state.
The solution could have multiple functions, or be recursive, or be iterative.
As as sanity check to make sure my assumptions were valid, I did this myself, live:
I wrote this in about 20 minutes and then debugged it for another 10-20 minutes:
(and then I went back for another 2 minutes to fix the leading newline)
"use strict";
var data = {
foo: [
{
bar: [
{
baz: ["apples", "bananas"],
},
],
quux: [
{
do: ["red thing", "blue thing"],
},
],
},
],
grault: {
name: "Bob",
age: 37,
grumpy: false,
nullish: null,
},
answer: 42,
};
/*
foo:
- bar:
- baz:
- apples
- bananas
quux:
- do:
- "red thing"
- "blue thing"
*/
function toYaml(data, prefix = "", skipFirstPrefix = true) {
// string
// boolean
// number
// array
// object
// null
if (["string", "number", "boolean"].includes(typeof data) || null === data) {
return JSON.stringify(data);
}
if (Array.isArray(data)) {
if (!data.length) {
return "[]";
}
return data
.map(function (val, i) {
let myPrefix = `\n${prefix}`;
if (0 === i && skipFirstPrefix) {
myPrefix = "";
}
return `${myPrefix}- ` + toYaml(val, prefix + " ", true);
})
.join("");
}
// must be an object (or not a valid JSON-able object in the first place)
let keys = Object.keys(data);
if (!keys.length) {
return "{}";
}
return keys
.map(function (k, i) {
let myPrefix = `\n${prefix}`;
if (0 === i && skipFirstPrefix) {
myPrefix = "";
}
return `${myPrefix}${k}: ` + toYaml(data[k], prefix + " ", false);
})
.join("");
}
Edit: Updated to handle empty arrays and empty objects.