const isObject = x => x !== null && typeof x === 'object';

const getKeys = object => {
    if (!isObject(object)) {
        return [''];
    }

    let result = [];

    Object.keys(object).forEach(key => {
        getKeys(object[key]).forEach(subKey => {
            result.push(subKey ? `${key}.${subKey}` : key);
        });
    });

    return result;
};

const getValue = (obj, path) => {
    let [value, i, paths] = [obj, 0, path.split('.')];
    for (i = 0; i < paths.length && isObject(value); ++i) {
        value = value[paths[i]];
    }

    if (i < paths.length || value === undefined || isObject(value)) {
        return '';
    }

    return value;
};

/**
 * @param {Array} arr
 * @return {Matrix}
 */
const jsonToMatrix = function(arr) {
    let keySet = arr.reduce((keys, key) => {
        getKeys(key).forEach(k => keys.add(k));
        return keys;
    }, new Set());

    let keys = Array.from(keySet).sort();

    let matrix = [keys];
    arr.forEach(obj => {
        matrix.push(keys.map(key => getValue(obj, key)));
    });
    return matrix;
};